If I have a simple childcontrol that already have a style defined for a element in the childcontrol. Can I change that style of that element from the parent control?
If I dont set the style in the childcontrol I can override it from the parent control, but I cant seem to get it to work when the style is set.
I can't change the code in the childcontrol.
The example childcontrol:
<UserControl
x:Class="TestingThemes.ChildControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TestingThemes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources>
<Style x:Key="aw" TargetType="Button">
<Setter Property="Foreground" Value="Blue" />
</Style>
</UserControl.Resources>
<Grid>
<Button
Width="100"
Height="50"
Content="Kalle Anka"
<!-- If I remove the style I can override it from parent control -->
Style="{DynamicResource aw}" />
</Grid>
</UserControl>
The parentcontrol:
<Grid>
...
<local:ChildControl>
<local:ChildControl.Resources>
<!--<Style BasedOn="{StaticResource local:ResourceKey=aw}" TargetType="Button">-->
<Style TargetType="Button">
<Setter Property="Foreground" Value="Red" />
</Style>
</local:ChildControl.Resources>
</local:ChildControl>
</Grid>
CodePudding user response:
This is possible, but you must change the location of the initial Style
.
The XAML engine will traverse the logical tree to lookup StaticResource
/DynamicResource
resources for an element (e.g., Button
) starting locally, with the local ResourceDictionary
.
This means, you want the default Style
that is defined inside the UserControl
to be found at the very end of the lookup route - after any potential custom styles that are intended to override the default Style
. To accomplish this, you must move the Style
either to App.xaml or Generic.xaml.
Additionally, the reference must be DynamicResource
in order to defer the lookup to the moment the logical tree is composed. The overriding Style
can be defined anywhere up the route towards the tree root.
Since Generic.xaml provides a different name scope, you would have to define a unique static (global in terms of the XAML name scopes) ComponentResourceKey
which you would have to use as the style's x:Key
value (in case you plan to move the default Style to the Generic.xaml file).
Because of the aforementioned XAML resource lookup behavior, creating a custom Control
is always prefereable over a UserControl
when you plan to make the control customizable (like in your case). The default Style
of a custom Control
is located in the Generic.xaml by default, thus you would have never ran into your current issue.
ChildControl.xaml
<UserControl>
<Grid>
<Button Style="{DynamicResource aw}" />
</Grid>
</UserControl>
App.xaml
The last lookup location before the Generic.xaml. If a Style
with the same key was not found yet, the Style
found in App.xaml
will be applied.
<Style x:Key="aw" TargetType="Button">
<Setter Property="Foreground" Value="Blue" />
</Style>
ParentControl.xaml
<ChildControl>
<ChildControl.Resources>
<Style x:Key="aw" TargetType="Button">
<Setter Property="Foreground" Value="Red" />
</Style>
</ChildControl.Resources>
</ChildControl>