Reusing existing templates in custom WPF controls - wpf

I am creating a custom WPF control class which inherits from ComboBox. As I am just defining behavior, the exiting ComboBox templates are fine for my purposes and I don't want to created a whole set of templates to support different themes. Is there a way to specify that my control uses the existing ComboBox templates?

Give your control a default style and set BasedOn to the default style of ComboBox:
<Style TargetType="{x:Type local:CustomControl1}"
BasedOn="{StaticResource {x:Type ComboBox}}">
</Style>
This will inherit the template setter from the ComboBox default style.

You don't have to do anything. If your control inherits from ComboBox and you don't override the DefaultStyleKey property, it will use the same style as ComboBox (thus the same template)

Related

Style Triggers Cause Control To Lose Theme

I have a WPF application using MahApps Metro for it's UI theming. I also need to use style triggers so I can appropriately determine whether a control is visible based on a property. The triggers work, but have the side effect of removing the theme. So now it looks like a default WPF unthemed CheckBox. Is there any way to preserve the MahApps Metro theme on the CheckBox?
When you assign a style, you overwrite the default style or any style applied before. If you want to extend a style, you have specify the base style using the BasedOn property.
Styles can be based on other styles through this property. When you use this property, the new style will inherit the values of the original style that are not explicitly redefined in the new style.
Specify the control type to base your style on the implicit style of the control.
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}">
<!-- ...your setters and triggers. -->
</Style>
Specify the key of the style that you want to base your style on.
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource MyCheckBoxBaseStyle}">
<!-- ...your setters and triggers. -->
</Style>
The named styles for CheckBox in MahApps can be found here on GitHub.
Please be aware that although your Visibility triggers should work, other triggers that are already defined in the control template of the CheckBox styles take precedence and you will not be able to redefine them in your own style. If you ever hit that case, you have to copy the corresponding style from GitHub into your project and adapt it to your requirements.

Setting implicit style of custom control in WPF

My custom control's default style is defined in Generic.xaml and is working fine.
However, when I try to change the style of my custom control the same way as one can with built in controls nothing happens. In App.xaml I am trying to change the default style of my control by doing the following:
<Style TargetType="{x:Type my:CustomControl}">
<Setter Property="Background" Value="Red"/>
</Style>
If I set the x:key property of the above style and reference this style using this key all works fine.
Is it correct that the above styling method only works for built in controls and does not work for custom controls, or am I just doing something wrong? Is there a workable solution to achieve this type of styling for custom controls?
Update
In this situation my custom control is derived from System.Windows.Window.
I finally managed to get implicit styling for my custom control to work. Apparently implicit styling might not work for derived controls as the style is not automatically being applied to the control. In order to achieve this one has to manually set the resource reference. My custom control now looks like this:
public class CustomControl : Window
{
static CustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
}
public CustomControl()
{
SetResourceReference(StyleProperty, typeof(CustomControl));
}
}
Yes, you are correct. Generic.xaml is used for custom controls, and App.xaml for application-wide resources (including styles for built-in controls). Specifying TargetType for a custom control in App.xaml will not work. So using explicit styles (with x:Key) seems to be the easiest solution.

Derive from Control and then allow others to apply a style

I have derived a new control from Control base class and set the DefaultStyleKeyProperty in the static constructor so that the appropriate style from Generic.xaml is used to defined the ControlTemplate. This all works fine and I get the expected appearance of several buttons etc.
Now I want to add some Style instances that customize the settings of my new control, such as the font and foreground color. But when I assign the style to the custom controls Style property it seems to remove the original default style and so it no longer has any appearance.
This doesn't seem quite right. The TabControl has a default style but you can still assign a Style to the TabControl.Style property that only modifies the Foreground color and it will not remove the rest of the TabControl appearance in the process.
Any ideas what I am doing wrong?
Declare your new style based on the default:
<Style TargetType={x:Type MyControl} BasedOn={StaticResource {x:Type MyControl}>

WPF Custom Control based on TabItem and Themes

I have a Generic.xaml theme created that sets styles for all common controls, including TabItem
This them is applying ok to all controls in the application
When I create a TabItem control and display it, it gets the Theme OK.
TabItem t = new TabItem();
t.Header = "Normal";
MainContentControl.Items.Add(t);
However when i create a Custom Control based on TabItem
public partial class ClosableTab : TabItem
and display it
ProActive.LocalControls.ClosableTab ct = new ProActive.LocalControls.ClosableTab();
ct.Header = "COMP";
MainContentControl.Items.Add(ct);
The theme is ignored.
I have tried over writing its defaultstyle using
DefaultStyleKeyProperty.OverrideMetadata(typeof(ClosableTab), new FrameworkPropertyMetadata(typeof(TabItem)));
Why if my custom control is based on a TabItem is the theme not also applying to it?
DefaultStyleKey is only used for looking up theme styles. Theme styles must be defined in the assembly defining the control or in a related assembly according to the ResourceDictionaryLocation specified in the control assembly. The TabItem themes are in PresentationFramework.Aero and WPF will look for ClosableTab themes in your assembly, so even if they have the same key it won't find them. Here is a good description of how WPF looks up theme styles.
Implicit styles will always be looked up using the actual type of the control, so if you have a <Style TargetType="TabItem"> in your resource dictionary then it won't affect a ClosableTab.
The easiest way to have ClosableTab inherit the implicit style from TabItem is to create an implicit style for ClosableTab and use BasedOn:
<Style TargetType="local:ClosableTab" BasedOn="{StaticResource {x:Type TabItem}}" />

WPF style problem with custom control and textbox-derived class

I had the following situation:
main application has app.xaml, which sets the Style for TextBox controls
a custom control is implemented in a separate DLL, and uses several TextBox controls
The main application's TextBox Style is applied to the custom control's TextBox controls. Cool!
My problem comes in because I need to use a class derived from TextBox in the custom control. Now the main app's TextBox Style is no longer applied. Can the custom control DLL have something like "app.xaml" where I can set the style for all my derived TextBox controls? Or can the main application somehow set the Style for all TextBox-derived classes?
Thanks!
You can set the BasedOn property of the custom TextBox style to the base style. Should automatically derive from whichever base style it inherits, in this case your application-level style.
<Style x:Key="CustomControlStyle" TargetType="{x:Type local:CustomControl}" BasedOn="{x:Type TextBox}">

Resources