ItemTemplateSelector in WPF Datagrid with AutoGenerateColumns

In our data grid, we use ItemTemplateSelector

to switch between two data templates based on data bound to a specific cell.

Since the number of columns depends on the current dataset, we use AutoGenerateColumns

in ours DataGrid

.

It looks like this particular combination doesn't work well - the
template selector isn't even called.

Is it possible to use a template selector on a data grid where columns are generated automatically?

Specifically: is it possible to use XAML without injecting logic into the code file, or use custom behavior?

The definition of the data is pretty trivial:

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

      

Defining an element template selector :

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

      

+3


source to share


2 answers


Firstly,

ItemTemplate and ItemTemplateSelector are inherited properties that are intentionally ignored in the DataGrid because they don't really apply to the DataGrid as they were intended in the ItemsControl.

Secondly, if you mean you want to change the cell templae based on its value you are looking for CellTemplateSelector

, on DataGridTemplateColumn

.

However, when auto-creating columns, it automatically selects base types.



You can override this behavior on an event GeneratingColumns

.

See this: Force DataTemplateCell with CellTemplateSelector in WPF DataGrid Auto Generated Columns

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

+6


source


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

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 created, 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 window resources, I have matching templates.

It can be done via DataTemplateSelector, but there was no time.

0


source







All Articles