DataGrid的自定义列模板

时间:2013-12-18 12:05:16

标签: c# wpf xaml data-binding datagrid

我有一个绑定到DataTable.DefaultView的DataGrid,它使用自动生成列来呈现网格。那部分工作正常。但是,对于某些列,我想使用自定义模板。问题是表中的列会在每次加载时发生变化,因此解决方案必须是通用的。

我可以按照here描述的方式挂钩AutoGeneratingColumn事件,但仍然有定义模板绑定的问题:

<UserControl.Resources>
    <DataTemplate x:Key="customCellTemplate">
        <TextBlock Text="{Binding ???"></TextBlock>
    </DataTemplate>
</UserControl.Resources>

(...)

<DataGrid ItemsSource="{Binding DefaultView}" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn">
</DataGrid>

我的代码背后:

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    string colName = e.PropertyName;
    if (someCondition)
    {
        var templateColumn = new DataGridTemplateColumn();
        templateColumn.Header = colName;
        templateColumn.CellTemplate = (DataTemplate)Resources["customCellTemplate"];
        templateColumn.SortMemberPath = colName;
        e.Column = templateColumn;
     }

正如您所看到的,我不知道如何在列模板中定义绑定,因为列名称会更改。

修改

除了接受的答案之外 - 有时按照此处所述以编程方式创建整个模板更容易: http://fczaja.blogspot.com/2013/12/wpf-datagrid-custom-template-for.html

1 个答案:

答案 0 :(得分:1)

使用StaticResource强制你保持相同 - 记住,静态意味着只有一个实例,所以如果你改变一个列的绑定,你将为所有这些更改它。所以它必须是这样的:

<DataTemplate x:Key="customCellTemplate">
    <TextBlock Text="{Binding}"></TextBlock>
</DataTemplate>

我以为你可以通过使用ContentControl将它包装在另一个DataTemplate中,以动态方式使用此模板。动态设置Content属性,并使用ContentTemplate的静态模板:

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    string colName = e.PropertyName;
    if (someCondition)
    {
        string xaml = @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""><ContentControl Content=""{0}"" ContentTemplate=""{1}"" /></DataTemplate>";
        var tmpl = (DataTemplate)XamlReader.Load(string.Format(xaml, "{Binding " + colName + "}", "{StaticResource customCellTemplate}"));
        var templateColumn = new DataGridTemplateColumn();
        templateColumn.CellTemplate = tmpl;
        templateColumn.Header = colName;
        templateColumn.SortMemberPath = colName;
        e.Column = templateColumn;
     }
}

唯一的问题是,通过此设置,我相信必须在应用程序级别定义“customCellTemplate”。