How to display DataGrid Column header in 2 lines?

4 posts, 1 answers
  1. Scott
    Scott avatar
    2 posts
    Member since:
    Mar 2018

    Posted 18 Apr 2018 Link to this post

    Unable to find anything on the Xamarin Forms UI forum that solves this,
    have looked at this - https://www.telerik.com/forums/several-xamarin-datagrid-questions
    and this on the UI for Windows forum - https://www.telerik.com/forums/how-to-display-datagrid-column-header-in-2-lines
    I've tried using a DataGridTemplateColumn:

    <grid:DataGridTemplateColumn CanUserEdit="False"
                                 HeaderText="Title">
        <grid:DataGridTemplateColumn.HeaderContentTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
     
                    <Label Text="Distance" />
                    <Label Text="(miles)" Grid.Row="1" />
                </Grid>
            </DataTemplate>
        </grid:DataGridTemplateColumn.HeaderContentTemplate>
        <grid:DataGridTemplateColumn.CellContentTemplate>
            <DataTemplate>
                <Grid>
                    <Label Text="{Binding JourneyDistance}" />
                </Grid>
            </DataTemplate>
        </grid:DataGridTemplateColumn.CellContentTemplate>
    </grid:DataGridTemplateColumn>

    Which returns - No property, bindable property, or event found for 'CellContentTemplate', or mismatching type between value

    Also tried a DataGridTextColumn.HeaderContentTemplate using both a StackLayout

    <grid:DataGridTextColumn CanUserEdit="False"
                             PropertyName="JourneyDistance">
        <grid:DataGridTextColumn.HeaderContentTemplate>
            <DataTemplate>
                <StackLayout>
                    <Label Text="Line 1" />
                    <Label Text="Line 2" />
                </StackLayout>
            </DataTemplate>
        </grid:DataGridTextColumn.HeaderContentTemplate>
    </grid:DataGridTextColumn>

     

    and a Grid inside the template

    <grid:DataGridTextColumn CanUserEdit="False"
                             PropertyName="JourneyDistance">
        <grid:DataGridTextColumn.HeaderContentTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
     
                    <Label Text="Distance" />
                    <Label Text="(miles)" Grid.Row="1" />
                </Grid>
            </DataTemplate>
        </grid:DataGridTextColumn.HeaderContentTemplate>
    </grid:DataGridTextColumn>

    The last snippet runs without error but the header is just empty

    Help please.

  2. Lance | Manager Technical Support
    Admin
    Lance | Manager Technical Support avatar
    1168 posts

    Posted 18 Apr 2018 Link to this post

    Hello Scott,

    Thank you for sharing the code, I have built you a demo (attached) that shows how to use your HeaderContentTemplate, in conjunction with DataGridHeaderStyle, to get the desired a multi-line column header:



    <grid:DataGridTextColumn CanUserEdit="False"
                             HeaderText="Distance"
                             PropertyName="JourneyDistance">
        <grid:DataGridTextColumn.HeaderStyle>
            <grid:DataGridColumnHeaderStyle TextMargin="2"  />
        </grid:DataGridTextColumn.HeaderStyle>
        <grid:DataGridTextColumn.HeaderContentTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
     
                    <Label Text="Distance" />
                    <Label Text="(miles)"
                           Grid.Row="1" />
                </Grid>
            </DataTemplate>
        </grid:DataGridTextColumn.HeaderContentTemplate>
    </grid:DataGridTextColumn>


    You'll see that the HeaderStyle object provides you with a lot of options to customize the header's appearance:




    If you have any further trouble, please open a support ticket and attach the problematic code so that we can investigate further.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Scott
    Scott avatar
    2 posts
    Member since:
    Mar 2018

    Posted 20 Apr 2018 Link to this post

    Hi Lance

    Thanks for your help here,

    Ultimately your solution was correct although I ended up loosing a few hours productivity because the text colour decided to default to white (facepalm), so finally I ended up with:

    <grid:DataGridTextColumn CanUserEdit="False"
                    HeaderText="Distance"
                    PropertyName="SomeProperty">
        <grid:DataGridTextColumn.HeaderStyle>
            <grid:DataGridColumnHeaderStyle TextMargin="2" />
        </grid:DataGridTextColumn.HeaderStyle>
        <grid:DataGridTextColumn.HeaderContentTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
     
                    <Label Margin="4,4,4,0"
                        Text="Line 1"
                        TextColor="{StaticResource ColourGridHeaderText}" />
                    <Label Margin="4,0,4,4"
                        Text="Line 2"
                        TextColor="{StaticResource ColourGridHeaderText}"
                        Grid.Row="1" />
                </Grid>
            </DataTemplate>
        </grid:DataGridTextColumn.HeaderContentTemplate>
    </grid:DataGridTextColumn>

     

    On a separate note the heading row is now a little uneven in height, see attached,

    how would I go about making the header a consistent height that is also scalable?

  4. Answer
    Lance | Manager Technical Support
    Admin
    Lance | Manager Technical Support avatar
    1168 posts

    Posted 20 Apr 2018 Link to this post

    Hi Scott,

    I'm not able to replicate this on my side with the amount of code I have, but my answer would likely be the same in any case.

    This is due to the margins on the template's child elements and the reduced header height ?. Although you've set a zero margin for the top and bottom Labels, there is still 8px in the middle plus the 4px (2+2) TextMargin set in the style.

    I recommend start with no margins and then gradually increment until you push out the parent container, that'll be your limit.

    If you have to a larger header, you can move your HeaderStyle to a resource and share it across all the columns so that the appearance is consistent.

    <ContentPage.Resources>
        <ResourceDictionary>
            <grid:DataGridColumnHeaderStyle x:Key="MyColumnHeaderStyle" TextMargin="2"   />
        </ResourceDictionary>
    </ContentPage.Resources>


    <grid:RadDataGrid x:Name="DataGrid"
                      AutoGenerateColumns="False">
        <grid:RadDataGrid.Columns>
            <grid:DataGridTextColumn PropertyName="Destination"
                             CanUserEdit="False"
                             HeaderText="Destination"
                             HeaderStyle="{StaticResource MyColumnHeaderStyle}"/>
            <grid:DataGridTextColumn CanUserEdit="False"
                             HeaderText="Distance"
                             PropertyName="JourneyDistance"
                             HeaderStyle="{StaticResource MyColumnHeaderStyle}">
                <grid:DataGridTextColumn.HeaderContentTemplate>
                    ...
                </grid:DataGridTextColumn.HeaderContentTemplate>
            </grid:DataGridTextColumn>
        </grid:RadDataGrid.Columns>
    </grid:RadDataGrid>


    As far as the text scaling with the display, you could use a Xamarin.Forms FontSize enum which will provide the appropriate font size for the device and screen. See the Xamarin.Forms Fonts article for more information. Here's a quick example:

    <Label FontSize="Large"/>
    <Label FontSize="Small"/>

    Alternatively, you could try using a Xamarin.Forms text Style: which also adapts to the device.

    <Label Text="Check out my style." Style="{StaticResource LabelStyle}" />

    Worst case scenario, if you need a finer level of control, you could hook into the ContentPage SizeChanged event and dynamically set the things you want larger:

    private void StartPage_OnSizeChanged(object sender, EventArgs e)
    {
        var page = sender as ContentPage;
     
        var isLarge = page.Height > 600;
     
        if (isLarge)
        {
            // make things larger
        }
        else
        {
            // make things smaller
        }
    }


    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top