Custom control default style

2019-09-12 08:30发布

问题:

I like to separate some of my custom controls to a dll.

lets assume I have the following example control:

MyControl.cs

namespace MyControlsNs {
    public class MyControl : ContentControl {
        public static DependencyProperty IsGreatProperty =
            DependencyProperty.Register("IsGreat",
                                    typeof (bool),
                                    typeof (MyControl),
                                    new PropertyMetadata(true));
        public bool IsGreat { 
            get { return (bool) GetValue(IsGreatProperty); }
            set { SetValue(IsGreatProperty, value); }
        }
    }
}

MyControl.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="clr-namespace:MyControlsNs"> 
    <Style x:Key="MyControl" TargetType="controls:MyControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsGreat}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

If I'd like to use MyControl I actually do the following:

<UserControl x:Class="MyMainViewClass"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:controls="clr-namespace:MyControlsNs">
    <UserControl.Resources>
        <ResourceDictionary Source="MyControl.xaml" />
    </UserControl.Resources>
    <controls:MyControl IsGreat="true" Style="{StaticResource MyControl}" />
</UserControl>

My goal is keeping the the definition of RD and Style, when I use it in MyMainViewClass; like this:

<UserControl x:Class="MyMainViewClass"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:controls="clr-namespace:MyControlsLib.MyControlsNs;assembly=MyControlsLib">
    <controls:MyControl IsGreat="true" />
</UserControl>

How can I define my default Style for MyControl? I found this thread Creating default style, but integrating didn't work for me:

static MyControl() {
   DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl))); 
}

回答1:

A default Style for a custom control in a library is located in a file named Generic.xaml in a folder named Themes in your library project.

Note also that a default Style resource does not have the x:Key attribute set.

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:MyControlsNs"> 
    <Style TargetType="controls:MyControl">
        ...
    </Style>
</ResourceDictionary>

Overriding the default value of the DefaultStyleKey dependency property of the custom control makes sure that the default Style is actually applied to the correct control type:

static MyControl()
{
    DefaultStyleKeyProperty.OverrideMetadata(
        typeof(MyControl),
        new FrameworkPropertyMetadata(typeof(MyControl))); 
}

Finally, you would also have to set the ThemeInfo attribute in your library's AssemblyInfo.cs:

[assembly: ThemeInfo(ResourceDictionaryLocation.None,
                     ResourceDictionaryLocation.SourceAssembly)]

Please see the Control Authoring Overview article on MSDN for further reading.



标签: c# wpf dll styles