2

I have a DataGrid style in App.xaml:

<Style TargetType="{x:Type DataGrid}">
    <Setter Property="Foreground" Value="{StaticResource DataGridItemTextBrush}" />
    <Setter Property="VerticalGridLinesBrush" Value="{StaticResource GridBrush}" />
    <Setter Property="HorizontalGridLinesBrush" Value="{StaticResource GridBrush}" />
    <Setter Property="RowBackground" Value="Transparent" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="HeadersVisibility" Value="Column" />
    <Setter Property="AlternatingRowBackground" Value="#77000000" />
</Style>

This works great for all of my datagrid's in my applications. However, for one of my datagrids, I want to group my rows if a specific column shares the same values. So I use the following on that particular datagrid:

<DataGrid.GroupStyle>
    <GroupStyle>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Path=Name}" Padding="3"/>
                </StackPanel>
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}" >
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type GroupItem}">
                            <Expander>
                                <Expander.Resources>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Setter Property="Foreground" Value="White" />
                                    </Style>
                                </Expander.Resources>
                                <Expander.Header>
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock Text="{Binding Path=Name, StringFormat=Set: {0}}" Margin="5,0"/>
                                        <TextBlock Text="{Binding Path=ItemCount, StringFormat=(\{0\} Games)}"/>
                                    </StackPanel>
                                </Expander.Header>
                                <ItemsPresenter />
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>
</DataGrid.GroupStyle>

Problem: Now this DataGrid displays everything correctly based on my DataGrid style, except it displays the text (foreground) as black instead of my style.

Solution: I can fix the problem (though I don't understand why this is necessary) by modifying my ItemsPresenter to either of the following:

<ItemsPresenter TextElement.Foreground="{StaticResource DataGridItemTextBrush}"/>

or

<ItemsPresenter TextBlock.Foreground="{StaticResource DataGridItemTextBrush}" />

Question: Can anyone explain why this happens and/or offer a better solution that will guarantee that my ItemsPresenter does not override any of my DataGrid styles?

Thank you!

H.B.
  • 166,899
  • 29
  • 327
  • 400
Scott
  • 11,840
  • 6
  • 47
  • 54

1 Answers1

3

Styling cascades down unless the child opts to override the imposed style. The ItemsPresenter in your case has default values; which you are not overriding within your DataGrid style. Either create an ItemsPresenter style within App.xaml to meet your needs or modify the value locally via an explicit or implicit style, or opt for your proposed solution.

Also keep in mind that you can use the BasedOn property to inherit the default styling; overriding only certain properties.

BasedOn="{StaticResource {x:Type DataGrid}}"
Aaron McIver
  • 24,527
  • 5
  • 59
  • 88
  • Alas... an answer! Better late than never right? A couple of things... 1) Why does ItemsPresenter only change my DataGrid's 'Foreground', but not its 'Background' (for example, if I change my DataGrid's Style's background to green instead of Transparent) 2)Setting the Style of an ItemsPresenter to be BasedOn the style of a DataGrid throws an exception. – Scott Aug 16 '11 at 18:10
  • I do have simple workarounds to fix my problem... but my big concern is "Why does ItemsPresenter change my DataGrid's foreground, yet it does not change the DataGrid's other properties such as Background." ItemsPresenter doesn't even have a 'Foreground' property... so it's not like it has its own default value for 'Foreground'. And if it did... it would be inherited from the DataGrid's style. – Scott Aug 16 '11 at 18:15
  • 1
    @Scotss The DataGrid BasedOn ref was to inherit the standard look of the DataGrid, versus starting from scratch. The ItemsPresenter doesn't have Foreground property but it must render the text it is presenting and a control within the ControlTemplate most likely exists which does this, hence you changing the Foreground via the TextBlock type. Create a default style for TextBlock within your local XAML file, make the Foreground Red and see what happens. – Aaron McIver Aug 16 '11 at 20:14
  • so I played around with things and finally figured out that it's not the ItemsPresenter breaking my style inheritance. If I set my Expander's foreground to red, everything inherits it properly. If I set my GroupItem's Foreground to red in a Style setter, nothing inherits it. If I set the Style for my GroupItem to be BasedOn my DataGrid's Style... everything inherits properly. I still don't understand why... but I was clearly focusing on the wrong problem a year ago. I have a feeling it has something to do with the ControlTemplate for GroupItem, or the GroupItem Style itself. – Scott Aug 19 '11 at 14:33
  • I still gave you an upvote and the answer for suggesting using BasedOn as it works if I use it with my GroupItem Style. – Scott Aug 19 '11 at 14:46
  • Where do you put the `BasedOn` ? – Xaalek Jun 15 '22 at 16:12