用于行的WPF DataGrid StyleSelector

时间:2016-04-27 05:36:19

标签: c# wpf mvvm mahapps.metro

我试图使用ItemContainerStyleSelector在数据网格中显示不同的行样式,基于定义行的对象的类型(ItemsSource是IGridItem的集合,有{{1和} GridItem应该有不同的风格)。我的问题是,我的StyleSelector的GridSeparator从未被调用过。现在我发现(here)问题可能是一个继承的样式(MahApps Metro库重新定义了所有标准控件的默认样式),这可能已经设置了ItemContainerStyle。

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

编辑:
手动将ItemContainerStyle设置为SelectStyle没有效果,我的StyleSelector的null仍未被调用。

EDIT2:
由于我没有像Grx70那样得到SelectStyle,我认为ItemContainerStyle不是问题,就像我最初想的那样。

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

我目前的实施:

System.Windows.Data Error: 24 : Both 'ItemContainerStyle' and 'ItemContainerStyleSelector' are set; 'ItemContainerStyleSelector' will be ignored.

Syle选择器:

<DataGrid ItemsSource="{Binding Items}" ItemContainerStyleSelector="{StaticResource StyleSelector}">

带有测试值的GridResources.xaml:

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;
    }
}

3 个答案:

答案 0 :(得分:3)

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

总而言之,这应该适合你:

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

此外,要修改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>

答案 1 :(得分:1)

您可以通过明确将其设置为ItemContainerStyle来覆盖默认null

<DataGrid ItemsSource="{Binding Items}"
          ItemContainerStyle="{x:Null}"
          ItemContainerStyleSelector="{StaticResource StyleSelector}">

答案 2 :(得分:0)

GridRowStyleSelector类的构造函数是静态和私有的。 尝试删除“静态”#39;此类中的关键字,并使构造函数公开。