2

I'm cleaning up App.xaml and moved some styles into Generic.xaml. But then, these styles don't have any effect. Why? Is this correct thing to do to make App.xaml tidy?

EDIT (to include some source code):

The goal is to restyle WPF DataGrid to make the scrollbars run from top to bottom and from left to right (default style excludes row and column header).

The style is working when I put it in App.xaml. Because it's a big chunk of code, I'd like to move it out of App.xaml into /Themes/DataGridEx.xaml. By the way, DataGridEx is my extended class derived from WPF DataGrid.

This is my DataGrid.xaml:

<ControlTemplate x:Key="SelectAllButtonTemplate" TargetType="{x:Type Button}"> <Grid> <Rectangle x:Name="Border" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" SnapsToDevicePixels="True" /> <Polygon x:Name="Arrow" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="8,8,3,3" Opacity="0.15" Fill="Black" Stretch="Uniform" Points="0,10 10,10 10,0" /> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="Border" Property="Stroke" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" /> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="Border" Property="Fill" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" /> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="Arrow" Property="Visibility" Value="Collapsed" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <Style TargetType="{x:Type local:DataGridEx}" x:Key="{x:Type local:DataGridEx}"> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="BorderBrush" Value="#FF688CAF" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" /> <Setter Property="ScrollViewer.CanContentScroll" Value="true"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:DataGridEx}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True" Padding="{TemplateBinding Padding}"> <ScrollViewer Focusable="false" Name="DG_ScrollViewer"> <ScrollViewer.Template> <ControlTemplate TargetType="{x:Type ScrollViewer}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <!--Left Column Header Corner --> <Button Command="{x:Static local:DataGridEx.SelectAllCommand}" Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, Path=CellsPanelHorizontalOffset}" Template="{StaticResource SelectAllButtonTemplate}" Focusable="false" Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, Path=HeadersVisibility, Converter={x:Static local:DataGridEx.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.All}}" /> <!--Column Headers--> <DataGridColumnHeadersPresenter Grid.Column="1" x:Name="PART_ColumnHeadersPresenter" Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Column}}"/> <!--DataGrid content--> <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Grid.Row="1" Grid.ColumnSpan="2" CanContentScroll="{TemplateBinding CanContentScroll}" /> <!-- Changed Grid.Row="1" to Grid.Row="0" Grid.RowSpan="2" to make the scrollbar start from top --> <ScrollBar Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Name="PART_VerticalScrollBar" Orientation="Vertical" Maximum="{TemplateBinding ScrollableHeight}" ViewportSize="{TemplateBinding ViewportHeight}" Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/> <!--Grid Grid.Row="2" Grid.Column="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type dg:DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ScrollBar Grid.Column="1" Name="PART_HorizontalScrollBar" Orientation="Horizontal" Maximum="{TemplateBinding ScrollableWidth}" ViewportSize="{TemplateBinding ViewportWidth}" Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/> </Grid--> <!-- Make the scrollbar to start from left edge --> <ScrollBar Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Name="PART_HorizontalScrollBar" Orientation="Horizontal" Maximum="{TemplateBinding ScrollableWidth}" ViewportSize="{TemplateBinding ViewportWidth}" Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/> </Grid> </ControlTemplate> </ScrollViewer.Template> <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsGrouping" Value="true"> <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> </Trigger> </Style.Triggers> </Style> 

This is my Themes/Generic.xaml:

<ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/Themes/DataGridEx.xaml"/> <ResourceDictionary Source="/Themes/GridComboBox.xaml"/> </ResourceDictionary.MergedDictionaries> 

This is my App.xaml:

 <Application x:Class="MyApp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyApp.Common" DispatcherUnhandledException="Application_DispatcherUnhandledException"> <!--StartupUri="MainWindow.xaml"--> <Application.Resources> <ResourceDictionary x:Key="rd"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Themes/Generic.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> .... </Application.Resources> </Application> 

With this code, I got a run-time XamlParseException: "Failed to create a 'Type' from the text 'local:DataGridEx'". However, if I comment out the MergedDictionaries in App.xaml, it doesn't complain, but the style doesn't take effect either.

Another interesting thing is that, in this generic.xaml I have two dictionaries. If I remove the ResourceDictionary from App.xaml, GridComboBox.xaml is working fine, but DataGridEx.xaml is not.

1
  • Is this really the WHOLE content of the DataGrid.xaml file? Commented Oct 26, 2021 at 21:00

2 Answers 2

3

You need to merge it into App.xaml like this:

<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Generic.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> 

If you are already doing that, you need to post your code to give more info.

EDIT: Try following the instructions here. Particularly, the parts about having to set your dictionaries to Resource and using the full path in Source.

Sign up to request clarification or add additional context in comments.

3 Comments

Why do I need to merge explicitly? Isn't it merged automatically when it is placed in Themes folder?
I changed the ThemeInfo to your suggestion, but it doesn't make any difference. I tried several things and run into different problems. I'll post my code in my question.
By the way, as I found out from a different test, it doesn't work if I set the build action for the generic.xaml to Resource, but it works fine if the build action is set to the default "Page".
0

I encountered this issue and the simplest fix for this is to remove the x:Key property of the style to be used in the ResourceDictionary.

<ControlTemplate TargetType="{x:Type Button}"> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.