我想知道是否可以根据ItemsSource集合中项目的类型更改wpf数据网格中列的样式。
我有一个来自wpf工具包的wpf数据网格。网格中的单个行应根据ItemsSource集合中的项目类型进行样式设置。因此,所有项目都具有相同的基类类型,但某些派生类型的列应该具有不同的样式。
这可能吗?
谢谢: - )
答案 0 :(得分:4)
仅限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>
通过将ContentTeresenter夹在CellTemplate内的DataTemplate中,我们可以获得所需的结果。
答案 1 :(得分:2)
是的,可以通过多种方式实现。我想要的是编写自己的自定义“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>