WPF Style Inheritace - how to automatically inherit style from base control
-
Thursday, April 24, 2008 4:29 PMHi!
I'm writing TabControl descendant:
public class MyTabControl:TabControl
{
...
}
I want my control to look 100% same like original TabControl for any theme.
At first I have trying to write something like:
static MyTabControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyTabControl), new FrameworkPropertyMetadata(typeof(TabControl)));
}
It doesn't help.
Hext time I tryed to write something like
<Style TargetType="{x:Type local:MyTabControl}" BasedOn="{StaticResource {x:Type TabControl}}" />
into Window.xaml
It works but I doesn't want to write this every time. Those controls are in some assembly. And I tried to create Generic.xaml under Themes folder:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:aaa">
<Style TargetType="{x:Type Controls:UnselectableTabControl}"
BasedOn="{StaticResource {x:Type TabControl}}"
>
</Style>
</ResourceDictionary>
but it doesn't help...
All Replies
-
Monday, April 28, 2008 4:33 AMWhen overriding a Control, as long as you don't override its default style, the derived control will pick up the style of the base control, so basically you can simply do this:
public class MyTabControl : TabControl
{
}
And you are done with it.
Hope this helps -
Monday, April 28, 2008 12:27 PMCode Snippet
using
System;using
System.Windows;using
System.Windows.Controls;public
class MyButtonDemo: Button{
[
STAThread] public static void Main(string[] a){
var application = new Application(); var uri = new Uri( "PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component\\themes/aero.normalcolor.xaml", UriKind.Relative); application.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);
var w = new Window{
Title = "MyButtonDemo - window", SizeToContent = SizeToContent.WidthAndHeight};
var sp = new StackPanel(); sp.Children.Add(new Button { Content = "WPF Button"}); sp.Children.Add(new MyButtonDemo { Content = "WPF Button Descendant" }); w.Content = sp; application.Run(w);}
}
produce such window: ( http://img247.imageshack.us/img247/7678/14628692dy0.png ) -
Tuesday, April 29, 2008 6:40 AM
The Style get messed up because you explicitly load the aero theme dictionary and merge it into application level, the Styles within the explicitly loaded theme dictionary will be treated as explicit styles, and they will override the default theme styles coming from the theme dictionary (in your case, it will be PresentationFramework.Classic.dll) which matches the system theme of your OS.
You could put below Style definition at App.Resources resource dictionary to workaround this issue:
<Style x:Key="{x:Type local:MyButtonDemo}" BasedOn="{StaticResource {x:Type Button}}"/>
Note that you need to add this style to the App.Resources dictionary after loading and merging the Aero theme dictionary.
hope this helps -
Tuesday, April 29, 2008 10:56 AM
Yes, placing <Style x:Key="{x:Type local:MyButtonDemo}" BasedOn="{StaticResource {x:Type Button}}"/> helps.
But the main question - is it possible to avoid this inclusion for this scenario.
Actually I'm developing some control library wich will be used across multiple projects in own company. And I don't want force every project to include such style for EVERY control used
. So I need 100% same behavior as built-in WPF controls have.
Thanks a lot for Your help!
-
Wednesday, April 30, 2008 3:06 AM
dimzon wrote:
But the main question - is it possible to avoid this inclusion for this scenario.
No, because when merging dictionary in the way you did above, you were effectively override the theme style coming from theme dictionary, the implicit style look up will look up style based on the Type object as a key. That's why you need to explicitly specifiy a Typed key aka x:Key="{x:Type cc:MyButton}".
Hope this helps

