簡體   English   中英

帶有AutoGenerateColumns的WPF Datagrid中的ItemTemplateSelector

[英]ItemTemplateSelector in WPF Datagrid with AutoGenerateColumns

在我們的數據網格中,我們使用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>

第一,

ItemTemplate和ItemTemplateSelector是在DataGrid中故意忽略的繼承屬性,因為它們並不像ItemsControl中那樣真正應用於DataGrid。

其次,如果您想根據其值修改單元格模板,則需要在DataGridTemplateColumn上查找CellTemplateSelector

但是,當您自動生成列時,它已自動選擇基礎類型。

您可以在GeneratingColumns事件中覆蓋該行為。

請參閱: 在WPF DataGrid自動生成列中使用CellTemplateSelector強制DataTemplateCell

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

我最近遇到了這個問題並以這種方式解決了它:

我們可以繼承類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完成,但沒有時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM