wpf数据网格中的不同单元样式取决于ItemsSource中的数据类型

时间:2009-07-29 07:55:13

标签: wpf datagrid toolkit

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

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

这可能吗?

谢谢: - )

2 个答案:

答案 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>