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.
Related
I'm creating the custom control. And suddenly faced a question: why to put control's style separately from the control?
I mean that using the standard way you must: derive from base control (for example, from TextBox) and add a style for it in general.xaml.
But why can't we do just like this:
<TextBox x:Class="CustomTest.CoolTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBox.Style>
<Style>
<Setter Property="TextBox.FontSize" Value="20" />
</Style>
</TextBox.Style>
</TextBox>
And code-behind:
public partial class CoolTextBox : TextBox
{
public CoolTextBox()
{
InitializeComponent();
}
}
Update #1
I'm not writing my own library but creating a custom control inside my main executable. Application support themes but they differ only by colors. So each theme is a set of brush resources and my style will refer them using DynamicResource.
What I want to know is the drawbacks of that solution. I mean performance, simplicity of usage and etc.
WPF allows changing themes at runtime, means the style shall be stored separatly from the controls. Futhermore the control shall be lookless when designining in order to other programmers to have their custom styles though somewhere there should be a default style which must be stored separatly in a Generic.xaml file. If your app doesn't support changing themes then you can define the style wherever you wish.
If you are writing a library of custom controls I suggest you to stick to standards.
Here is a link how shall a custom controls be created:
http://wpftutorial.net/HowToCreateACustomControl.html
In addition to dev hedgehog's answer about performance, I found the following drawbacks:
Style object is own for each instance of control. So you end up with number of clones of the same Style object.
You cannot override style using BasedOn property. Only completely replace is possible.
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}>
I've create a style for ListItems that I want to use across all ListBoxes in my application. I can set these manually like so:
<ListBox ItemContainerStyle="">
But I'm having trouble getting the style to apply to every single ListBox in my application without touching each one and adding the above attribute.
In addition, and more importantly, I want to apply the style to list boxes used within custom templated controls. Right now I have to modify the Generic.xaml theme in the control library... not something i think I should have to do.
Fairly certain this has something to do with themes, btu having a heck of a time figuring it out.
You can do this with implicit styles in Silverlight 4.
Define your style in the regular way:
<Style x:Key="DefaultListBoxStyle" TargetType="ListBox">
....
<Style>
then create the implicit style:
<Style TargetType="ListBox"
BasedOn="{StaticResource DefaultListBoxStyle}" />
you could use implicit styles.
http://www.silverlightshow.net/items/Implicit-Styles-in-Silverlight-4.aspx
You define one global style for a type (in your case ListBoxItem) and then this style is the new default style for your app.
If you need any further information, just leave a comment.
BR,
TJ
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}}" />
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}">