Extending Default Style of Parent Control in CustomUserControl not working - wpf

I am trying to extend an implicit Style of a control which is defined in any parent control within a custom UserControl. This doesn't seem to work as I would expect.
The scenario would be: Including a ResourceDictionary in MainWindow.xaml which defines a default theme. Than I want to extend a base Style which is defined in that theme within my UserControl.
What I have already tried:
Having a MainWindow.xaml which defines the following DefaultStyle in its Resources:
<Window x:Class="UserControl_Style_Inheritance.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:UserControl_Style_Inheritance"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Blue"></Setter>
</Style>
</Window.Resources>
<Grid>
<local:MyUserControl></local:MyUserControl>
</Grid>
</Window>
And having a MyUserControl.xaml which should extend the defined DefaultStyle of MainWindow.xaml:
<UserControl x:Class="UserControl_Style_Inheritance.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:UserControl_Style_Inheritance"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="BorderBrush" Value="Red"></Setter>
</Style>
</UserControl.Resources>
<Grid>
<Button>Hello</Button>
</Grid>
</UserControl>
But MyUserControl is based on the normal Button Style by having a gray background instead of a blue background of the Style defined in MainWindow.xaml.
What am I doing wrong, or where am I thinking into the wrong direction?
Edit: Putting the default Style into the Application.xaml file works, but this is not what I want to do.

Try adding the button style to App.xaml:
<Application.Resources>
<Style x:Key="BtnStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Blue"></Setter>
</Style>
</Application.Resources>
And use it in your UserControl like this:
<UserControl.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BtnStyle}">
<Setter Property="BorderBrush" Value="Red"></Setter>
</Style>
</UserControl.Resources>
<Grid>
<Button>Hello</Button>
</Grid>

Related

How to add additional styles to a window which is already using a style template

How to add additional styles to window style when it already using a style like in below?
<Style x:Key="MyWindowStyle" TargetType="Window">
<Setter Property="Control.Background" Value="PaleGreen"/>
<Setter Property="Window.Title" Value="Styled Window"/>
</Style>
My main window is:
<Window x:Class="Binding.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Binding"
mc:Ignorable="d"
Style="{StaticResource MyWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Label Content="Test Window" />
</StackPanel>
</Window>
So I want to use MyWindowStyle but say I also want to add additional styles like adding the following:
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="BorderBrush" Value="Red"/>
How do I do that? I can't figure out the syntax.
Problem is that when you use StaticResouce the resource has to be initialized before the usage.
In your case you have the resource inside the window therefor it is not initialized before the window is initialized.
Use DynamicResource instead and it will work:
<Window x:Class="Binding.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Binding"
mc:Ignorable="d"
Style="{DynamicResource MyWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style x:Key="MyWindowStyle" TargetType="{x:Type Window}">
<Setter Property="Control.Background" Value="PaleGreen"/>
<Setter Property="Window.Title" Value="Styled Window"/>
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="BorderBrush" Value="Red"/>
</Style>
</Window.Resources>
<StackPanel>
<Label Content="Test Window" />
</StackPanel>
</Window>
See more here about WPF Resources.
You can define MyWindowStyle2 and use it.
<Style x:Key="MyWindowStyle2" TargetType="Window" BasedOn="{StaticResource MyWindowStyle}">
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="BorderBrush" Value="Red"/>
</Style>
Or
here

Unnamed Style that can be used with BasedOn in UserControls

I am looking for a XAML-only way to define an unnamed style in a particular Window that affects all TextBoxes, even those inside UserControls.
Here is an example: suppose I have one particular Window in which I want to set the Foreground property to Red for all TextBoxes, including those contained in UserControls. I am trying to do it like this:
<Window x:Class="WpfApplication1.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Width="300"
SizeToContent="Height">
<Window.Resources>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Style.Setters>
<Setter Property="Foreground" Value="Red"/>
</Style.Setters>
</Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
<TextBox Text="A-Regular"/>
<TextBox Text="B-Bold">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Style.Setters>
<Setter Property="FontWeight" Value="Bold"/>
</Style.Setters>
</Style>
</TextBox.Style>
</TextBox>
<local:MyUserControl/>
<TextBox Text="C-Regular"/>
</StackPanel>
</Window>
The used UserControl looks like this:
<UserControl x:Class="WpfApplication1.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Vertical">
<TextBox Text="Like A, but in UserControl"/>
<TextBox Text="Like B, but in UserControl">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Style.Setters>
<Setter Property="FontWeight" Value="Bold"/>
</Style.Setters>
</Style>
</TextBox.Style>
</TextBox>
</StackPanel>
</UserControl>
The resulting window is:
screenshot of window
Everything is OK, except for the TextBox "Like B, but in UserControl", which is bold and black. I would have expected to see red text, like in all other TextBoxes.
Is there a way to have the unnamed style in the Window's resource affect all TextBoxes in the UserControl, even those that expand the current TextBox's style using BasedOn?
I am looking for a way where I do not have adapt all places where I "call" the UserControl (i.e. where I have <local:MyUserControl/> in the Window). Nor do I want to have to adapt the UserControl itself, because it might be within a third-party library.
Just put Style into <Application.Resources>

Referencing resource inside usercontrol not working

I have a Wpf Application with the following structure
MainSolution -> Views (folder) -> NextGenDG (WPF Project) ->DisplayResources(folder) -> BRUserControlStyles.xaml
Here is BRUserControlStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:NextGenDG.DisplayResources">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="/NextGenDG;component/DisplayResources/BRColors.xaml" />
<ResourceDictionary
Source="/NextGenDG;component/DisplayResources/BRFonts.xaml" />
<ResourceDictionary
Source="/NextGenDG;component/DisplayResources/BRButtonStyles.xaml" />
<ResourceDictionary
Source="/NextGenDG;component/DisplayResources/BRCommonControlStyles.xaml" />
<ResourceDictionary
Source="/NextGenDG;component/DisplayResources/BRToggleButtonStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style
x:Key="UserControlDarkBackgroundStyle"
TargetType="{x:Type UserControl}"
BasedOn="{StaticResource {x:Type UserControl}}">
<Setter
Property="Margin"
Value="0" />
<Setter
Property="Padding"
Value="0" />
<Setter
Property="Background"
Value="Red" />
<Style.Resources>
<Style
TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonLightTextGradientDarkBackgroundStyle}" />
<Style
TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource TextBlockLightTextStyle}" />
<Style
TargetType="{x:Type ToggleButton}"
BasedOn="{StaticResource ToggleButtonLightTextGradientDarkBackgroundStyle}" />
<Style
TargetType="{x:Type Separator}"
BasedOn="{StaticResource SeparatorDarkLineStyle}" />
</Style.Resources>
</Style>
</ResourceDictionary>
Now I am trying to use the style inside a UserControl that is inside a folder called UserControls as follows. This UserControl is being called in the MainWindow
<UserControl x:Class="NextGenDG.UserControls.NextGenHeaderCartridgeStatusUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:NextGenDG.UserControls"
mc:Ignorable="d"
Style="{DynamicResource UserControlDarkBackgroundStyle}"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBlock Grid.Column="1"
Text="{Binding Text}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
</UserControl>
Problem is if I say StaticResource UserControlDarkBackgroundStyle it complains saying the resource is not found. So when I use DynamicResource UserControlDarkBackgroundStyle it dosen't apply the style. Please help. At a glace is my ResourceDictionary path correct?

Why the WPF Window always get Default Style?

I have tried to set the Style for WPF Window in XAML. I am able to see my changes in VS Designer, but when I run the application it will always get the default Style.
Not Working:
<Style TargetType="Window">
<Setter Property="Background" Value="Red"/>
</Style>
If I give that Style with Key and applying that Style to Window then it is working.
Working:
<Style x:Key="window" TargetType="Window">
<Setter Property="Background" Value="Red"/>
</Style>
There is any reason need to give Style with key for Window?
Can any one please explain what is going on?
It is necessary to add construction in Window:
Style="{StaticResource {x:Type Window}}"
Style is in the file App.xaml:
<Application x:Class="WindowStyleHelp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<!-- In this case, the key is optional -->
<Style x:Key="{x:Type Window}" TargetType="{x:Type Window}">
<Setter Property="Background" Value="Pink" />
</Style>
</Application.Resources>
</Application>
Window in XAML:
<Window x:Class="WindowStyleHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Style="{StaticResource {x:Type Window}}"
WindowStartupLocation="CenterScreen">
<Grid>
</Grid>
</Window>
Try
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="Red"/>
</Style>
Target types in style doesn't get applied on derived types.
Either you use StaticResource to apply key on all your windows -
<Application x:Class="WpfApplication4.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="MyStyle" TargetType="Window">
<Setter Property="Background" Value="Red"/>
</Style>
</Application.Resources>
</Application>
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Style="{StaticResource MyStyle}">
OR
Define a style for your type (derived window) in resources like this -
<Application x:Class="WpfApplication4.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="Background" Value="Red"/>
</Style>
</Application.Resources>
</Application>

How do I let my UserControls use the same styles as App.xaml?

I have a UserControl with a Border element within it that I want to style with a particular Border style. It compiles but won't start, giving a XamlParseException, saying, "Cannot find resource ..."
Is there a way to do this?
Thanks.
App.xaml:
<cal:CaliburnApplication x:Class="WahnamProgressTracker.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
xmlns:Converters="clr-namespace:WahnamProgressTracker.Converters;assembly=WahnamProgressTracker"
xmlns:Model="clr-namespace:WahnamProgressTracker.Model">
<Application.Resources>
<Style x:Key="FancyBorder"
TargetType="{x:Type Border}">
<Setter Property="Margin" Value="0,0,0,8"/>
<Setter Property="Padding" Value="8"/>
...
</Style>
</Application.Resources>
MainView.xaml:
<Window x:Class="WahnamProgressTracker.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
xmlns:uc="clr-namespace:WahnamProgressTracker.UserControls"
MinHeight="500" MinWidth="800">
<DockPanel>
<uc:MainViewMenu x:Name="menu"
DockPanel.Dock="Top" />
<StatusBar x:Name="quoteBar"
DockPanel.Dock="Bottom">
<TextBlock Text="{Binding Path=Quote.Text, Mode=OneWay}" />
</StatusBar>
<uc:MainViewNavigation x:Name="navigationBar"
DockPanel.Dock="Left" />
<uc:ProgressGraph x:Name="graph" />
</DockPanel>
MainViewNavigation.xaml (user control):
<UserControl x:Class="WahnamProgressTracker.UserControls.MainViewNavigation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Border Style="{StaticResource FancyBorder}">
...
</Border>
</UserControl>
Can you post a sample of what you mean? The only case in which your issue can occur is if the User Control is created and then rendered outside your application's visual tree.
The XAML below works for me:
App.xaml:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<Style TargetType="{x:Type TextBlock}" x:Key="myStyle">
<Setter Property="Foreground" Value="Green" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Application.Resources>
</Application>
Window1.xaml:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<local:UserControl1 />
</Grid>
</Window>
UserControl1.xaml:
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<TextBlock Style="{StaticResource myStyle}">HEY!</TextBlock>
</Grid>
</UserControl>

Resources