开发者

How to change content of a WPF datagrid cell, depending on objecttype

开发者 https://www.devze.com 2023-04-03 10:13 出处:网络
I have a collection consisting of two different object types, with the same base class. subclass A needs to display a button in a cell and subclass B needs to display a checkbox in a cell (the same co

I have a collection consisting of two different object types, with the same base class. subclass A needs to display a button in a cell and subclass B needs to display a checkbox in a cell (the same column).

Ho开发者_JAVA技巧w do I accomplish this in a wpf datagrid?


The code below is purely for guidance and is not tested for compilation...

  1. You should use DataGridTemplateColumn for this.

  2. Specify the DataGridTemplateColumn.CellTemplate as follows

    <DataTemplate>
       <Grid>
           <Button Visibility="{Binding BaseClassPropertyValue,
                         Converter={StaticResource SubclassToVisibilityConverter},
                              ConverterParameter='Button'}"/>
           <ChecBox Visibility="{Binding BaseClassPropertyValue,
                         Converter={StaticResource SubclassToVisibilityConverter},
                              ConverterParameter='CheckBox'}"/>
       </Grid> 
    </DataTemplate>
    
  3. In SubclassToVisibilityConverter.Convert() method use the following logic...

    if (parameter == "Button")
    {
      if (value is ClassA)
      {
         return Visibility.Visible;
      }
      else
      {
         return Visbility.Collapsed;
      }
    }
    else if (parameter == "CheckBox")
    {
      if (value is ClassB)
      {
         return Visibility.Visible;
      }
      else
      {
         return Visbility.Collapsed;
      }
    }
    

Let me know if this helps.


You could always try this:

ObservableCollection<MyBaseClass> myCollection = new ObservableCollection<MyBaseClass>;
myCollection.Add(new Subclass_A());
myCollection.Add(new Subclass_B());

...

Create DataTemplates for each subclass and wire up your myCollection to DataGrid. At this point you'll have Grid filled with two types (Subclass_A, Subclass_B). The magic is to use DataTemplateSelector on your DataGrid:

<DataGrid ItemTemplateSelector="{DynamicResource GridTemplateSelector}">

having this, the Grid (majority of containers in fact) will ask for DataTemplate when drawing an item and apply accordingly.

namespace MyNamespace
{
    public class GridTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;

            if (element != null && item != null && item is Subclass_A)
            {
                return element.FindResource("Subclass_A_DataTemplate") as DataTemplate;
            }

            if (element != null && item != null && item is Subclass_B)
            {
                return element.FindResource("Subclass_B_DataTemplate") as DataTemplate;
            }
        }
    }
} 


Create two DataTemplates and specify DataType for each template. Then put the content into DataGridTemplateColumn:

<DataGrid>
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ContentControl Content="{Binding}">
                        <ContentControl.Resources>
                            <DataTemplate DataType="ClassA">
                                <Button />
                            </DataTemplate>
                            <DataTemplate DataType="ClassB">
                                <CheckBox />
                            </DataTemplate>
                        </ContentControl.Resources>
                    </ContentControl>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>
0

精彩评论

暂无评论...
验证码 换一张
取 消