简体   繁体   中英

How can I make a Custom Control automatically apply a style defined in a resource dictionary?

I have a control library with a custom control :

public class GlassButton : Button {
}

and I have also defined a resource dictionary to style the control :

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:Animations="clr-namespace:WPFTools.Classes"
    xmlns:Controls="clr-namespace:WPFTools.Controls"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    mc:Ignorable="d">
    <Style TargetType="{x:Type Controls:GlassButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">

I want to be able to simply drag and drop the GlassButton onto a window or control and NOT have to do this :

<Window.Resources>
    <ResourceDictionary Source="Foo"/>
</Window.Resources>

I've been able to do this once before but that knowledge seems to have been lost to me.

How can I make this happen? ( I'm fine making changes in the code behind of my control ).

I had to re-remember how this worked a week ago, and this is what I had to do to make it work for me. The typical way with custom controls is to define the style in a file named generic.xaml located in the Themes folder directly beneath your project root. Then you need to override the default style in the static constructor of your custom control class. It would look something like this:

public class GlassButton : Button
{
    static GlassButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata( typeof( GlassButton ),
            new FrameworkPropertyMetadata( typeof( GlassButton ) ) );
    }
}

Finally, you need to set the appropriate assembly property to say that your generic theme is located within your assembly. Something like this would go in your Properties\\AssemblyInfo.cs file:

using System.Windows;
[assembly:ThemeInfo( ResourceDictionaryLocation.None,
    ResourceDictionaryLocation.SourceAssembly )]

I'm not sure if this is strictly necessary, but I also had to change the Build Action property on my generic.xaml file to Page before the default style would get properly applied to my control.

The best practice for this work is creation DictionaryResources contains your all WPF Styles in application for every app style you want. 在此处输入图片说明

So you can remove your current style and add new style dynamically like below: 在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM