问题
I'm trying to use an ItemContainerStyleSelector to display different row styles in a datagrid, based on the type of the object defining the row (ItemsSource is a collection of IGridItem
s, there are GridItem
and GridSeparator
which should get different styles). my problem was, that the SelectStyle
of my StyleSelector was never called. Now I found out (here) the problem could be an inherited style (MahApps Metro library redefines the default styles of all standard controls), which probably already sets an ItemContainerStyle.
So now my question is: Is there a way to still use my StyleSelector, so that I have the inherited style as base for the selected styles? And if not, how do I achieve a different style just for some rows based on their object type?
EDIT:
Manually setting the ItemContainerStyle to null
didn't have an effect, SelectStyle
of my StyleSelector is still never called.
EDIT2:
Since I don't get System.Windows.Data Error: 24 : Both 'ItemContainerStyle' and 'ItemContainerStyleSelector' are set; 'ItemContainerStyleSelector' will be ignored.
like Grx70 asked, I assume that the ItemContainerStyle is not the problem, like I initially thought.
jstreet pointed out, that it's related to MahApps.Metro, though... (see his comment)
My current implementation:
<DataGrid ItemsSource="{Binding Items}" ItemContainerStyleSelector="{StaticResource StyleSelector}">
The Syle selector:
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;
}
}
GridResources.xaml with test values:
<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>
回答1:
I think I've found the culprit. Turns out that the proper way to handle row styles in DataGrid
is through RowStyle
and RowStyleSelector
properties and not ItemContainerStyle
and ItemContainerStyleSelector
. They work, but only until you explicitly use RowStyle
or RowStyleSelector
. That's exactly what MahApps Metro does - it sets RowStyle
value (I believe through overriding DataGrid
default style). Then I think ItemContainerStyle
is set internally by DataGrid
(some testing revealed that ItemContainerStyle
was set despite explicitly setting it to null
).
So to sum up, this should do the trick for you:
<DataGrid ItemsSource="{Binding Items}"
RowStyle="{x:Null}"
RowStyleSelector="{StaticResource StyleSelector}">
(...)
</DataGrid>
Also, to modify MahApps row style rather than discard it completely you should base your styles on the MahApps one:
<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>
回答2:
You can override the default ItemContainerStyle
by explicitly setting it to null
:
<DataGrid ItemsSource="{Binding Items}"
ItemContainerStyle="{x:Null}"
ItemContainerStyleSelector="{StaticResource StyleSelector}">
回答3:
The constructor of the GridRowStyleSelector class is static and private. Try removing the 'static' keywords from this class, and make the constructor public.
来源:https://stackoverflow.com/questions/36881121/wpf-datagrid-styleselector-for-rows