简体   繁体   中英

WPF add custom attribute for control style in ResourceDictionary

I am making a skin for WPF and store all the styles in ResourceDictionary. I wrote a button template which has many various colors, eg: PrimaryHover , PrimaryActive etc. If I want to add a new style with other colors, I'll need to copy and paste this code and replace colors in whole code. So as not to do this, I want to create custom properties which will contain colors and point them in the triggers. I created a class with properties but it's invisible inside the ResourceDictionary. How to do that?

<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
    <Setter Property="Background" Value="{StaticResource Primary}" />
    <Setter Property="Foreground" Value="{StaticResource White}" />
    <Setter Property="BorderBrush" Value="{StaticResource PrimaryBorder}"/>
    <Setter Property="BorderThickness" Value="0,1,0,0"/>
    <Setter Property="Padding" Value="5,0,5,0"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid SnapsToDevicePixels="True">
                    <Border x:Name="BkgBorder" CornerRadius="3" BorderThickness="{TemplateBinding BorderThickness}"
                            BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" Opacity="1">
                    </Border>

                    <ContentPresenter Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"/>

                </Grid>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter Property="Background" Value="{StaticResource PrimaryFocused}" TargetName="BkgBorder"/>
                        <Setter Property="BorderBrush" Value="{StaticResource PrimaryBorderFocused}" TargetName="BkgBorder"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True"/>
                            <Condition Property="IsEnabled" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" Value="{StaticResource PrimaryHover}" TargetName="BkgBorder"/>
                        <Setter Property="BorderBrush" Value="{StaticResource PrimaryBorderHover}" TargetName="BkgBorder"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsPressed" Value="True"/>
                            <Condition Property="IsEnabled" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" Value="{StaticResource PrimaryActive}" TargetName="BkgBorder"/>
                        <Setter Property="BorderBrush" Value="{StaticResource PrimaryBorderActive}" TargetName="BkgBorder"/>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Foreground" Value="{StaticResource White}"/>
                    </Trigger>

                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

and class

class Buttons
{
    public static SolidColorBrush GetHoverColor(DependencyObject obj)
    {
        return (SolidColorBrush)obj.GetValue(HoverColorProperty);
    }

    public static void SetHoverColor(DependencyObject obj, SolidColorBrush value)
    {
        obj.SetValue(HoverColorProperty, value);
    }

    public static readonly DependencyProperty HoverColorProperty =
        DependencyProperty.RegisterAttached("HoverColor", typeof(SolidColorBrush), typeof(MainWindow), new PropertyMetadata(new SolidColorBrush(Colors.Green)));

}

I was able to copy your class into a test project exactly as it is and use it just fine.

Are you maybe neglecting to set up the XAML Namespace ? My working example looks like this:

<Window x:Class="CSharpTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CSharpTest">

    <Button local:Buttons.HoverColor="Yellow"/>

</Window>

As a seperate note, keep in mind that with the way your proeprty is currently declared, it can be applied to any kind of DependencyObject . If you want to limit so it is only valid on Button s, then you should do this instead:

    public static SolidColorBrush GetHoverColor(Button obj)
    {
        return (SolidColorBrush)obj.GetValue(HoverColorProperty);
    }

    public static void SetHoverColor(Button obj, SolidColorBrush value)
    {
        obj.SetValue(HoverColorProperty, value);
    }

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