I'm trying to create a simple data grid in WinUI 3 that uses custom DataTemplate
that vary for the second column, creating different formatting for the second column's cells depending on the data type of the cell's data. A boolean would have a CheckBox
and a string would have a TextBox
.
I'm extending the DataTemplateSelector
class to achieve this, per this page: https://learn.microsoft.com/en-us/windows/apps/design/controls/data-template-selector
The problem is, my extension's override DataTemplateSelectorExt.SelectTemplateCore()
method shown below doesn't even run, so I can't even test if the template code is good. There are no errors, but the second column of the data grid only shows the namespace of the CustomInfo
class: ...ViewModels.CustomInfo
.
My first question is, what is preventing SelectTemplateCore()
from running and providing the second column with a custom DataTemplate
?
XAML
<Page.Resources>
<local:DataTemplateSelectorExt
x:Key="templateselctor"
CheckBoxTemplate="{StaticResource CheckBoxTemplateResource}"
TextBlockTemplate="{StaticResource TextBlockTemplateResource}"
TextBoxTemplate="{StaticResource TextBoxTemplateResource}" />
<DataTemplate x:Key="TextBlockTemplateResource" x:DataType="x:String">
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="TextBoxTemplateResource" x:DataType="x:String">
<Grid>
<TextBox Text="{x:Bind}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="CheckBoxTemplateResource" x:DataType="x:Boolean">
<Grid>
<CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{x:Bind}" />
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<DataGrid
x:Name="dataGrid1"
ItemsSource="{x:Bind ViewModel.CustomInfoItems}" >
<DataGrid.Columns>
<GridTextColumn
MappingName="CFieldDisplayName" />
<GridTemplateColumn
CellTemplateSelector="{StaticResource templateselctor}"
MappingName="CFieldValue" />
</DataGrid.Columns>
</DataGrid>
</Grid>
Code Behind
public sealed partial class MyPage : Page
{
public DataGridViewModel ViewModel { get; }
public MyPage()
{
this.InitializeComponent();
ViewModel = new DataGridViewModel();
}
}
public class DataTemplateSelectorExt : DataTemplateSelector
{
public DataTemplate TextBlockTemplate { get; set; }
public DataTemplate TextBoxTemplate { get; set; }
public DataTemplate CheckBoxTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{ //This line is never his with a breakpoint
if (item == null)
{
return TextBlockTemplate;
}
else if (item.GetType() == typeof(string))
{
return TextBoxTemplate;
}
else if (item.GetType() == typeof(bool))
{
return CheckBoxTemplate;
}
else
{
return TextBoxTemplate;
}
}
}
ViewModel
public DataGridViewModel()
{
CustomInfoItems = new ObservableCollection<CustomInfo>();
this.GenerateCutomInfoItems();
}
private void GenerateCutomInfoItems()
{
CustomInfoItems.Add(new CustomInfo() { CFieldDisplayName = "Custom TextBox Item", CFieldValue = "String Value" });
CustomInfoItems.Add(new CustomInfo() { CFieldDisplayName = "Custom CheckBox Item", CFieldValue = true });
}
public class CustomInfo
{
public string CFieldDisplayName { get; set; }
public object CFieldValue { get; set; }
}
As you can see in the doc, the DataTemplateSelector, the DataTemplateSelector
has two overridable methods.
In your case, try overriding the second one instead.