I can create a derived Button
class like the following, and I will automatically get the style from the default Button
public class Button2 : Button
{
}
However, I cannot seem to do the same with a custom control
public class X : ContentControl
{
static X()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(X), new FrameworkPropertyMetadata(typeof(X)));
}
}
public class Y : X
{
}
<Window.Resources>
<Style TargetType="{x:Type local:X}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:X}">
<Border Background="Red">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</Window.Resources>
<StackPanel>
<local:X>
<TextBlock Text="Hello world!" />
</local:X>
<local:Y>
<TextBlock Text="Hello world!" />
</local:Y>
<local:Button2>
<TextBlock Text="Hello world!" />
</local:Button2>
</StackPanel>
The above code will show nothing for the Y
control. I would expect it to pick up the style from X
Please note, I do not want to have to define a style for Y
, I want it to behave like Button2
where it picks up the base style without having to add anything to the Y
class.
I have had a look in the source for Button
here : https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Button.cs
but can't see anything special.
One workaround I have seen is to use :
public class X : ContentControl
{
public X()
{
SetResourceReference(StyleProperty, typeof(X));
}
}
But I am wondering why I don't see anything similar in the Button
source?
The default control Style should be declared in the file Themes\Generic.xaml
, which is automatically created if you add a Custom Control (WPF)
item to your Visual Studio project.
It would look like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomControlStyleTest">
<Style TargetType="{x:Type local:X}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:X}">
<Border Background="Red">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</ResourceDictionary>
Visual Studio then also creates an AssemblyInfo.cs
file with this content:
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None,
ResourceDictionaryLocation.SourceAssembly
)]
Having that, your class Y
would pick up the default Style from X
.