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>
You can override the default
ItemContainerStyle
by explicitly setting it tonull
:The constructor of the GridRowStyleSelector class is static and private. Try removing the 'static' keywords from this class, and make the constructor public.
I think I've found the culprit. Turns out that the proper way to handle row styles in
DataGrid
is throughRowStyle
andRowStyleSelector
properties and notItemContainerStyle
andItemContainerStyleSelector
. They work, but only until you explicitly useRowStyle
orRowStyleSelector
. That's exactly what MahApps Metro does - it setsRowStyle
value (I believe through overridingDataGrid
default style). Then I thinkItemContainerStyle
is set internally byDataGrid
(some testing revealed thatItemContainerStyle
was set despite explicitly setting it tonull
).So to sum up, this should do the trick for you:
Also, to modify MahApps row style rather than discard it completely you should base your styles on the MahApps one: