0

我想知道是否可以根据 ItemsSource 集合中的项目类型更改 wpf 数据网格中列的样式。

我有一个来自 wpf 工具包的 wpf 数据网格。网格中的单行应根据 ItemsSource 集合中的项目类型设置样式。因此,所有项目都属于相同的基类类型,但某些派生类型的列应该具有不同的样式。

这可能吗?

谢谢 :-)

4

2 回答 2

5

仅 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 中,我们实现了预期的结果。

于 2013-02-13T12:50:42.260 回答
4

是的,可以通过多种方式做到这一点。我会选择编写您自己的自定义“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>
于 2009-07-29T08:35:07.723 回答