You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3 DataGrid中DataTemplateSelector.SelectTemplateCore未执行问题排查

WinUI 3 DataGrid DataTemplateSelector 不执行的问题解决

问题场景

在WinUI3中搭建简易DataGrid,要求第二列根据CFieldValue的数据类型渲染不同控件:布尔值显示CheckBox,字符串显示TextBox。通过继承DataTemplateSelector实现了自定义选择器DataTemplateSelectorExt,但重写的SelectTemplateCore方法完全不触发,第二列仅显示CustomInfo类的命名空间。

问题原因

  1. 缺少必要的方法重载:WinUI3的DataGrid调用DataTemplateSelector时,会使用带DependencyObject参数的SelectTemplateCore重载,仅实现object item参数的版本不会被调用。
  2. GridTemplateColumn绑定配置错误:只设置MappingName无法让选择器正确获取CFieldValue的值,需要明确指定模板的绑定目标。
  3. DataTemplate的x:DataType冲突:模板中指定了x:DataType,但CFieldValue是object类型,x:Bind无法自动解析实际类型,导致绑定失效。

解决步骤及修改后代码

1. 修正DataTemplateSelector的方法实现

补充带DependencyObject参数的重载方法,确保DataGrid能正确调用选择逻辑:

public class DataTemplateSelectorExt : DataTemplateSelector
{
    public DataTemplate TextBlockTemplate { get; set; }
    public DataTemplate TextBoxTemplate { get; set; }
    public DataTemplate CheckBoxTemplate { get; set; }

    // WinUI3 DataGrid会调用这个重载
    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        return SelectTemplateCore(item);
    }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        if (item == null)
        {
            return TextBlockTemplate;
        }
        else if (item is string)
        {
            return TextBoxTemplate;
        }
        else if (item is bool)
        {
            return CheckBoxTemplate;
        }
        else
        {
            return TextBlockTemplate;
        }
    }
}

2. 调整XAML中的DataGrid列配置

通过ContentPresenter明确绑定到CFieldValue,并指定ContentTemplateSelector,替换原有的GridTemplateColumn直接设置CellTemplateSelector的方式:

<Page.Resources>
    <local:DataTemplateSelectorExt
        x:Key="templateselctor"
        CheckBoxTemplate="{StaticResource CheckBoxTemplateResource}"
        TextBlockTemplate="{StaticResource TextBlockTemplateResource}"
        TextBoxTemplate="{StaticResource TextBoxTemplateResource}" />

    <DataTemplate x:Key="TextBlockTemplateResource">
        <Grid>
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding}" />
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="TextBoxTemplateResource">
        <Grid>
            <TextBox Text="{Binding Mode=TwoWay}" />
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="CheckBoxTemplateResource">
        <Grid>
            <CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding Mode=TwoWay}" />
        </Grid>
    </DataTemplate>
</Page.Resources>

<Grid>
    <DataGrid
        x:Name="dataGrid1"
        ItemsSource="{x:Bind ViewModel.CustomInfoItems}">
        <DataGrid.Columns>
            <GridTextColumn
                MappingName="CFieldDisplayName" />
            <GridTemplateColumn Header="Field Value">
                <GridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <!-- 绑定到CustomInfo的CFieldValue属性,再用选择器选模板 -->
                        <ContentPresenter 
                            Content="{Binding CFieldValue}"
                            ContentTemplateSelector="{StaticResource templateselctor}" />
                    </DataTemplate>
                </GridTemplateColumn.CellTemplate>
            </GridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

3. 移除DataTemplate的x:DataType

因为CFieldValue是object类型,x:DataType会限制绑定的类型解析,直接使用{Binding}即可适配不同数据类型。

验证效果

修改完成后,SelectTemplateCore方法会被正常触发,第二列会根据CFieldValue的类型分别渲染TextBox或CheckBox,不再显示命名空间。

内容的提问来源于stack exchange,提问作者E. A. Bagby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:22:40