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...
You should use DataGridTemplateColumn for this.
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>
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>
精彩评论