ItemTemplateSelector in WPF Datagrid with AutoGenerateColumns

浪子不回头ぞ 提交于 2019-12-10 17:32:11

问题


In our data grid we're using an ItemTemplateSelector to switch between two data templates based on the data bound to a particular cell.

As the number of columns depends on the current data set we're using AutoGenerateColumns in our DataGrid.

It appears that this particular combination does not work well -
the template selector isn't even called.

Can we use the template selector in a data grid where columns are created automatically?

More specifically: Is this possible using XAML only w/o putting logic into the code-behind file or using custom behaviours?

Our data grid definition is fairly trivial:

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

The item template selector definition:

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

回答1:


First,

ItemTemplate and ItemTemplateSelector are inherited properties which are purposely ignored in the DataGrid since they don't really apply to DataGrid in the way that they were meant to in ItemsControl.

Secondly, if you mean that you want to modify cell templae based on its value, you are looking for CellTemplateSelector, on a DataGridTemplateColumn.

However, when you auto-generate columns, it already chooses the underlying types automatically.

You can override that behavior in GeneratingColumns event.

See this: Force DataTemplateCell with CellTemplateSelector in WPF DataGrid Autogenerated columns

If you need more control, you might want to take a look at https://zamjad.wordpress.com/2011/09/17/datagrid-with-dynamic-columns-revisited/




回答2:


I recently ran into this problem and solved it this way:

we can inherit the class 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;
    }
}

Next, in the event handler, where the column is generated, I do:

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;
    }
}

In the resources of the window I have the corresponding templates.

It is possible to do through DataTemplateSelector, but there was no time.



来源:https://stackoverflow.com/questions/27685735/itemtemplateselector-in-wpf-datagrid-with-autogeneratecolumns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!