I am using AppThemeBinding in my XAML pages and resource dictionaries to style my app based on the current theme. I have read the documentation surrounding using the GridStyle property of SfDataGrid to provide grid-level styles and the CellStyle property of the various grid column definitions like GridTextColumn.
It seems that the SfDataGrid does not handle AppThemeBinding extensions and throws an InvalidCastException when trying to apply the cell style to a GridCell:
<Style x:Key="SfGridCellStyle" ="sfdg:GridCell">
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={x:StaticResource BackgroundColorLight}, Dark={StaticResource BackgroundColorDark}}" />
<Setter Property="Foreground" Value="{AppThemeBinding Light={StaticResource TextColorLight}, Dark={StaticResource TextColorDark}}" />
<Setter Property="BorderColor" Value="{AppThemeBinding Light={StaticResource BorderColorLight}, Dark={StaticResource BorderColorDark}}" />
</Style>
Column definitions:
<sfdg:SfDataGrid.Columns>
<sfdg:GridTextColumn MappingName="Name" />
<sfdg:GridTextColumn HeaderText="Sales Stage" MappingName="Stage" />
<sfdg:GridTextColumn HeaderText="Last Activity Date" MappingName="LastActivityDate" />
</sfdg:SfDataGrid.Columns>
Additionally, the cell styles do not apply uniformly: I have supplied a ForegroundColor that should be white in dark mode with a dark background color but the actual result is white text on a white background, which is unreadable:
When using a GridTemplateColumn and specifying the same CellStyle, the background color applies correctly, but the template contents (a stack layout with an image and a label) do not display:
I'm having difficulty editing the text above since random parts disappear when I click edit so I will make an addendum here: In my column definitions, I have not specified the CellStyle attribute. Doing so causes the app to crash with the InvalidCastException, so the only way I can capture a screenshot of the grid appearing incorrectly is by disabling the cell styles and relying on the grid styles which don't seem to crash the app when using AppThemeBinding.
Hi Karthik,
I can confirm the issue has been fixed; however, when changing the system theme from light to dark or dark to light while a grid is displayed, the grid does not reflect the correct colors for the current theme after changing.
This theme change can be easily responded to using a standard documented Xamarin pattern and it would be greatly appreciated if the SfDataGrid could be further updated to support responding to app theme changes at runtime.
Is this a change that the team is willing to make, or am I left telling users to restart the app to see their theme changes? Some SyncFusion controls do respond to app theme changes, and others don't. It's very frustrating to have such inconsistencies.
|
public MainPage()
{ InitializeComponent(); Application.Current.RequestedThemeChanged += Current_RequestedThemeChanged; this.dataGrid.GridStyle = new CustomStyle(); this.dataGrid.SelectionChanging += DataGrid_SelectionChanging; this.dataGrid.QueryCellStyle += DataGrid_QueryCellStyle; } private void Current_RequestedThemeChanged(object sender, AppThemeChangedEventArgs e) { Application.Current.UserAppTheme = e.RequestedTheme; stack.Children.Remove(dataGrid); stack.Children.Add(dataGrid); } |
Thanks for looking into it, but I don't want to have to apply this workaround in every place we use SfDataGrids. We also use pure MVVM so I don't name my views or work on them from code-behind.
| <ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="local:CustomStackLayout">
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light=White, Dark=Black}" />
</Style>
<Style TargetType="local:CustomLabel">
<Setter Property="TextColor" Value="{AppThemeBinding Light=Black, Dark=Blue}" />
</Style>
<Style TargetType="syncfusion:GridCell">
<Setter Property="BorderColor" Value="{AppThemeBinding Light=Pink, Dark=Blue}" />
</Style>
<Style TargetType="Button">
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light=Yellow, Dark=Blue}" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.BindingContext>
<local:Datas x:Name="viewModel" />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout x:Name="stack">
<Button Text="ClickToScroll" Clicked="Button_Clicked"></Button>
<syncfusion:SfDataGrid x:Name="dataGrid" SelectionMode="Single" AllowEditing="True" NavigationMode="Cell" AutoGenerateColumns="False" ItemsSource="{Binding mycollect}" ColumnSizer="Star">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTemplateColumn MappingName="No_1">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<local:CustomStackLayout VerticalOptions="Center">
<local:CustomLabel HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="{Binding No_1}"></local:CustomLabel>
</local:CustomStackLayout>
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
</syncfusion:GridTemplateColumn>
<syncfusion:GridTemplateColumn MappingName="No_2">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<local:CustomStackLayout VerticalOptions="Center">
<local:CustomLabel HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="{Binding No_2}"></local:CustomLabel>
</local:CustomStackLayout>
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
</syncfusion:GridTemplateColumn>
<syncfusion:GridTemplateColumn MappingName="Text">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<local:CustomStackLayout VerticalOptions="Center">
<local:CustomLabel HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="{Binding Text}"></local:CustomLabel>
</local:CustomStackLayout>
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
</syncfusion:GridTemplateColumn>
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
</StackLayout> </ContentPage.Content>.... public class CustomStackLayout : StackLayout {
}
public class CustomLabel : Label
{
|
Yes I suppose that does work but, again, this is a workaround and not a really permanent solution. There are plenty of workarounds, but I'd like a permanent solution.
That's ok! I'll look forward to the update then. Thank you :)