This is a migrated thread and some comments may be shown as answers.

Issues with HeaderContentTemplate

1 Answer 191 Views
DataGrid
This is a migrated thread and some comments may be shown as answers.
Tien
Top achievements
Rank 1
Tien asked on 13 Mar 2020, 07:49 PM

-- GridIssuePage.xaml --

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:telerikGrid="clr-namespace:Telerik.XamarinForms.DataGrid;assembly=Telerik.XamarinForms.DataGrid"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="GridIssueDemo.GridIssuePage">
    <ContentPage.Content>
        <telerikGrid:RadDataGrid AutoGenerateColumns="False" x:Name="demoDataGrid">
        </telerikGrid:RadDataGrid>
    </ContentPage.Content>
</ContentPage>

-- GridIssuePage.xaml.cs --

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Telerik.XamarinForms.DataGrid;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace GridIssueDemo
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class GridIssuePage : ContentPage
    {
        public GridIssuePage()
        {
            InitializeComponent();

            var numberOfStableColumns = 7; // <- can change this
            for (var i = 0; i < numberOfStableColumns; i++)
            {
                demoDataGrid.Columns.Add(new DataGridTextColumn()
                {
                    PropertyName = "data" + i,
                    HeaderText = "stable_" + i
                });
            }

            var unstableColumnDataIndex = numberOfStableColumns;
            var customColumnHeaderTexts = new List<string> // can add items to list ("unstable_5", "unstable_6", ...)
                { "unstable_0", "unstable_1", "unstable_2", "unstable_3", "unstable_4"};
            foreach (var customHeaderText in customColumnHeaderTexts)
            {
                demoDataGrid.Columns.Add(new DataGridTextColumn()
                {
                    PropertyName = "data" + unstableColumnDataIndex++,
                    HeaderContentTemplate = new DataTemplate(() =>
                    {
                        var headerLabel = new Label()
                        {
                            Text = customHeaderText,
                            VerticalTextAlignment = TextAlignment.Center,
                            FontSize = 14,
                            LineBreakMode = LineBreakMode.WordWrap,
                            Margin = new Thickness(5, 4),
                            HeightRequest = Device.RuntimePlatform == Device.iOS ? 40 : 33.715
                        };
                        return headerLabel;
                    })
                });
            }

            var intRand = new Random();
            var mockDataItems = new List<dynamic>();
            var dataItemRowCount = 15;
            var dataItemColumnCount = numberOfStableColumns + customColumnHeaderTexts.Count();
            for (var i = 0; i < dataItemRowCount; i++)
            {
                var mockDataItem = new System.Dynamic.ExpandoObject();
                var mockDataItemDict = mockDataItem as IDictionary<string, object>;
                for (var dataIndex = 0; dataIndex < dataItemColumnCount; dataIndex++)
                {
                    mockDataItemDict["data" + dataIndex] = intRand.Next(0, 100);
                }
                mockDataItems.Add(mockDataItem);
            }
            demoDataGrid.ItemsSource = mockDataItems;
        }

    }
}

-- --

I have attached two files that can hopefully be used to reproduce two issues I had with the HeaderContentTemplate defined in a DataGridTextColumn.

The first issue is the custom elements defined in HeaderContentTemplate gets shuffled when they go out of view and when they go into view again (for grid with width greater than the width of the device's screen). In the cs file I have attached, there are 5 columns defined with HeaderContentTemplate named "unstable_0", "unstable_1", "unstable_2", "unstable_3", "unstable_4". Let say for an Android smartphone in portrait mode, they are not visible by default because there are other columns to the left of them pushing them off-screen. When I swipe the screen to move to very right of the grid, the "unstable_" columns get rendered in the correct order. Afterward, if I swipe to move to the very left of the grid again so that I no longer see the "unstable_" columns, and then move to the very right of the grid again, instead of displaying index 0 -> 4, it displays in the reverse order (so now I see "unstable_4" -> "unstable_0"). If I move all the way to the left and all the way to the right again, I see the correct order for the "unstable_" columns again. 

This is likely caused by the underlying code that decides what elements to render next on the screen for header cells defined with HeaderContentTemplate.

The code seems to be doing this: At the beginning, before the "unstable_" columns are visible:

(imaginary data structure) headerLabelsToRenderNext: "unstable_0", "unstable_1", "unstable_2", "unstable_3", "unstable_4"

When I all the way to the right, headerLabelsToRenderNextList becomes empty and the "unstable_" header labels get rendered in the correct order on-screen.

When I swipe and move the grid to the left so that "unstable_4" column moves out of view, headerLabelsToRenderNext: "unstable_4"

When I swipe and move the grid to the left so that "unstable_3" column moves out of view, headerLabelsToRenderNext: "unstable_4", "unstable_3"

When I swipe and move the grid to the left so that all "unstable_" columns move out of view, headerLabelsToRenderNext: "unstable_4", "unstable_3",  "unstable_2", "unstable_1", "unstable_0",

Now when I swipe all the way to the right, the "unstable_" templated header cells' elements get displayed in a reverse order.

Please see if you can reproduce this behavior with the attached codes. The condition is that multiple of the "unstable_" columns have to be out of view first.

The second issue is that if there are more than 5 column header cells defined with HeaderContentTemplate, at least one of the templated header cell is going to get a repeated element. Let say if I have defined 6 template headers with labels: "unstable_0", "unstable_1", "unstable_2", "unstable_3", "unstable_4", "unstable_5", instead of displaying "unstable_0", "unstable_1", "unstable_2", "unstable_3", "unstable_4", "unstable_5" on-screen, what gets displayed is "unstable_0", "unstable_1"  "unstable_2", "unstable_3", "unstable_4", "unstable_0"

Let me know if these issues can be reproduced on your side and if there is a work-around for them.

1 Answer, 1 is accepted

Sort by
0
Didi
Telerik team
answered on 16 Mar 2020, 10:23 AM

Hello Tien,

Thank you for the provided code and details.

We have the issue with the horizontal scrolling and datagrid header content template logged as a bug report in our feedback portal. You can track its progress on the following link: https://feedback.telerik.com/xamarin/1366379-datagrid-columnheaders-are-inaccurately-visualized-when-headercontenttemplate-is-set-and-horizontal-scrolling-is-performed

The second issue is a result from the first one.

Workaround:

I can suggest you to use a DataGrid TemplateColumn, single template for the Header and bindings to it if you are using headers that look the same:

<telerikDataGrid:DataGridTemplateColumn HeaderText="Template Column">
    <telerikDataGrid:DataGridTemplateColumn.HeaderContentTemplate>
        <DataTemplate>
            <Label Text="{Binding HeaderText}"/>
        </DataTemplate>
    </telerikDataGrid:DataGridTemplateColumn.HeaderContentTemplate>
</telerikDataGrid:DataGridTemplateColumn>

For more details on the workaround please review the following forum thread:

https://www.telerik.com/forums/can-you-turn-off-ui-virtualization#0UEq6VkuPkm5W7efKe71VQ

Additional Information:

I have noticed that you are using ExpandoObjects for the mockDataItem. We have investigated in details the way the DataGrid is working with ExpandoObjects and unfortunately, with its current implementation the control is not able to handle and work properly with that type of objects. The DataGrid is still in development state and working with ExpandoObjects is an area that is not fully tested - while it looks like the control works in some cases with ExpandoObject, technically such functionality has never been implemented for it and it's more of a missing feature.  We have a feature request logged in our feedback portal. You can follow and vote for the item at the link below: https://feedback.telerik.com/xamarin/1366439-datagrid-add-support-for-visualization-of-dynamic-type-of-data

Please note that in the Forum only image attachments are allowed, if you want to send us a sample project or files different than images, please open a support ticket and attach them there. 

I hope the provided information was helpful.

Regards,
Didi
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
Tags
DataGrid
Asked by
Tien
Top achievements
Rank 1
Answers by
Didi
Telerik team
Share this question
or