【问题标题】:ItemTemplateSelector in WPF Datagrid with AutoGenerateColumns带有 AutoGenerateColumns 的 WPF Datagrid 中的 ItemTemplateSelector
【发布时间】:2014-12-29 08:37:57
【问题描述】:

在我们的数据网格中,我们使用ItemTemplateSelector 根据绑定到特定单元格的数据在两个数据模板之间切换。

由于列数取决于我们在DataGrid 中使用的AutoGenerateColumns 的当前数据集。

这种特殊的组合似乎效果不佳 -
模板选择器甚至没有被调用。

我们可以在自动创建列的数据网格中使用模板选择器吗?

更具体地说:这是否可能仅使用 XAML 将逻辑放入代码隐藏文件或使用自定义行为?

我们的数据网格定义相当简单:

 <DataGrid
     ItemTemplateSelector="{StaticResource myCustomDataTemplateSelector}"
     ItemsSource="{Binding MyData}">
     <DataGrid.Columns>
     </DataGrid.Columns>
 </DataGrid>

项目模板选择器定义

<UserControl.Resources>
    <ResourceDictionary>
        <helpers:CustomDataTemplateSelector x:Key="myCustomDataTemplateSelector"/>
    </ResourceDictionary>
</UserControl.Resources>

【问题讨论】:

  • 您确定您的 myCustomDataTemplateSelector 已在资源中实例化吗?另外,你在哪里定义模板
  • 假设是这样 - 定义添加到问题中。 DataTemplates 是在同一个文件的同一个资源部分中定义的 - 但它似乎并没有那么远..

标签: c# wpf mvvm datagrid itemtemplateselector


【解决方案1】:

首先,

ItemTemplate 和 ItemTemplateSelector 是继承的属性 在 DataGrid 中被故意忽略,因为它们并不真正适用于 DataGrid 以它们在 ItemsControl 中的意图。

其次, 如果您的意思是要根据其值修改单元格模板,您正在寻找CellTemplateSelector,在DataGridTemplateColumn 上。

但是,当您自动生成列时,它已经自动选择了基础类型。

您可以在 GeneratingColumns 事件中覆盖该行为。

看到这个:Force DataTemplateCell with CellTemplateSelector in WPF DataGrid Autogenerated columns

如果您需要更多控制,您可能需要查看https://zamjad.wordpress.com/2011/09/17/datagrid-with-dynamic-columns-revisited/

【讨论】:

  • 感谢您的提示!现在在行为中设置模板选择器以便触发它 - 尽管如此,SelectTemplate() 中的item 参数始终为空
  • @cacau: 总是,还是只在第一次通过?该方法应为每一列调用两次(一次用于设置逻辑树,第二次用于渲染)。 stackoverflow.com/questions/4268409/…
【解决方案2】:

我最近遇到了这个问题并以这种方式解决了:

我们可以继承类DataGridBoundColumn

public class DataGridProcessContainerColumn : DataGridBoundColumn
{
    public DataTemplate ContentTemplate { get; set; }

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        throw new NotImplementedException();
    }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        var control = new ContentControl();
        control.ContentTemplate = ContentTemplate;
        BindingOperations.SetBinding(control, ContentControl.ContentProperty, Binding);
        return control;
    }
}

接下来,在生成列的事件处理程序中,我这样做:

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    DataTemplate template = null;

    // Four lines below replace the DataTemplateSelector
    // You need to select the desired template according to your conditions
    if (e.PropertyType.IsAssignableFrom(typeof(IEnumerable<MyClass2>)))
        template = (DataTemplate)Resources["MyClass2CollectionTemplate"];
    else if (e.PropertyType.IsAssignableFrom(typeof(MyClass2)))
        template = (DataTemplate)Resources["MyClass2Template"];

    if (template != null)
    {
        var col = new DataGridProcessContainerColumn();
        col.Binding = (e.Column as DataGridBoundColumn).Binding;
        col.ContentTemplate = template;
        col.Header = e.Column.Header;
        e.Column = col;
    }
}

在窗口的资源中我有相应的模板。

可以通过DataTemplateSelector来做,但是来不及了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-07
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    相关资源
    最近更新 更多