我想知道是否可以根据 ItemsSource 集合中的项目类型更改 wpf 数据网格中列的样式。
我有一个来自 wpf 工具包的 wpf 数据网格。网格中的单行应根据 ItemsSource 集合中的项目类型设置样式。因此,所有项目都属于相同的基类类型,但某些派生类型的列应该具有不同的样式。
这可能吗?
谢谢 :-)
仅 WPF 的解决方案:
我参加聚会有点晚了,但是如果其他人试图做这样的事情,那么只有 WPF 的解决方案。没有 DataGridColumn 类可以直接查找正确的 DataTemplate 但我们可以像这样间接使用 ContentPresenter:
<Window.Resources>
<DataTemplate DataType="{x:Type models:Employee}">
<Grid>...</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type models:Manager}">
<Grid>...</Grid>
</DataTemplate>
</Window.Resources>
<DataGrid ... >
<DataGrid.Columns>
<DataGridTemplateColumn Header="MyColumn">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
通过将 ContentPresenter 夹在 CellTemplate 内的 DataTemplate 中,我们实现了预期的结果。
是的,可以通过多种方式做到这一点。我会选择编写您自己的自定义“typeswitch”转换器,该转换器根据输入类型选择一个值。像这样:
public class TypeSwitchConverter : Dictionary<Type, object>, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, .CultureInfo culture)
{
foreach (var mapping in this)
{
if (mapping.Key.IsAssignableFrom(value.GetType()))
{
return mapping.Value;
}
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后Style
为您的单元格模板中的顶级元素使用绑定,并根据需要使用上述转换器进行该绑定。这是一个简化的示例,ListBox
它使用它来样式化项目:
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}">
<TextBlock.Style>
<Binding>
<Binding.Converter>
<my:TypeSwitchConverter>
<Style x:Key="{x:Type cor:Int32}" TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="Red" />
</Style>
<Style x:Key="{x:Type cor:String}" TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="Green" />
</Style>
<Style x:Key="{x:Type sys:Uri}" TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="Blue" />
</Style>
</my:TypeSwitchConverter>
</Binding.Converter>
</Binding>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>