行的 WPF DataGrid StyleSelector

Flo*_*och 0 c# wpf mvvm mahapps.metro

我正在尝试使用 ItemContainerStyleSelector 根据定义行的对象的类型在数据网格中显示不同的行样式(ItemsSource 是IGridItems的集合,存在GridItem并且GridSeparator应该获得不同的样式)。我的问题是,SelectStyle我的 StyleSelector 从未被调用过。现在我发现(这里)问题可能是继承的样式(MahApps Metro 库重新定义了所有标准控件的默认样式),它可能已经设置了 ItemContainerStyle。

所以现在我的问题是:有没有办法仍然使用我的 StyleSelector,以便我将继承的样式作为所选样式的基础?如果没有,我如何根据对象类型为某些行实现不同的样式?

编辑:
手动设置 ItemContainerStylenull没有效果,SelectStyle我的 StyleSelector 仍然没有被调用。

EDIT2:
因为我System.Windows.Data Error: 24 : Both 'ItemContainerStyle' and 'ItemContainerStyleSelector' are set; 'ItemContainerStyleSelector' will be ignored.不像 Grx70 那样问,所以我认为 ItemContainerStyle 不是问题,就像我最初认为的那样。

jstreet 指出,它与 MahApps.Metro 相关,但是......(见他的评论)


我目前的实现:

<DataGrid ItemsSource="{Binding Items}" ItemContainerStyleSelector="{StaticResource StyleSelector}">
Run Code Online (Sandbox Code Playgroud)

Syle 选择器:

public class GridRowStyleSelector : StyleSelector
{
    private readonly ResourceDictionary _dictionary;

    public GridRowStyleSelector()
    {
        _dictionary = new ResourceDictionary
        {
            Source = new Uri(@"pack://application:,,,/myApp;component/View/GridResources.xaml")
        };
    }

    public override Style SelectStyle(object item, DependencyObject container)
    {
        string name = item?.GetType().Name;
        if (name != null && _dictionary.Contains(name))
        {
            return (Style)_dictionary[name];
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

带有测试值的 GridResources.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="GridItem" TargetType="DataGridRow">
        <Setter Property="BorderThickness" Value="3"/>
    </Style>
    <Style x:Key="GridSeparator"  TargetType="DataGridRow">
        <Setter Property="BorderBrush" Value="Red"/>
    </Style>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)

Grx*_*x70 5

我想我找到了罪魁祸首。事实证明,处理行样式的正确方法DataGrid是通过RowStyleRowStyleSelector属性而不是ItemContainerStyleItemContainerStyleSelector。它们有效,但只有在您明确使用RowStyleor 之前RowStyleSelector。这正是 MahApps Metro 所做的 - 它设置RowStyle值(我相信通过覆盖DataGrid默认样式)。然后我认为ItemContainerStyle是由内部设置的DataGrid(一些测试表明,ItemContainerStyle尽管明确设置为null)。

总而言之,这应该对你有用:

<DataGrid ItemsSource="{Binding Items}"
          RowStyle="{x:Null}"
          RowStyleSelector="{StaticResource StyleSelector}">
    (...)
</DataGrid>
Run Code Online (Sandbox Code Playgroud)

此外,要修改 MahApps 行样式而不是完全丢弃它,您应该将样式基于 MahApps 之一:

<Style x:Key="GridItem" TargetType="DataGridRow"
       BasedOn="{StaticResource MetroDataGridRow}">
    <Setter Property="BorderThickness" Value="3"/>
</Style>
<Style x:Key="GridSeparator" TargetType="DataGridRow"
       BasedOn="{StaticResource MetroDataGridRow}">
    <Setter Property="BorderBrush" Value="Red"/>
</Style>
Run Code Online (Sandbox Code Playgroud)