-- 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.