wpf 从自定义控件库中选择样式

wa7juj8i  于 2023-05-19  发布在  其他
关注(0)|答案(1)|浏览(174)

我希望有一个WPF Custom Control Library与多种风格,并能够访问不同的风格,为不同的使用。

例如

假设我有一个名为IconButtonControl的项目,其中有一个cs类文件,其中包含所有需要的依赖项,几个.xaml文件如下:Blue.Generic.xamlGreen.Generic.xaml(等等),其中它们都引用了主Generic.xaml使用<ResourceDictionary.MergedDictionaries>

Generic主文件(Generic.xaml)

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:IconButtonControl">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/IconButtonControl;component/Themes/Red.Generic.xaml"/>
        <ResourceDictionary Source="/IconButtonControl;component/Themes/Blue.Generic.xaml"/>
        <ResourceDictionary Source="/IconButtonControl;component/Themes/Green.Generic.xaml"/>
        <ResourceDictionary Source="/IconButtonControl;component/Themes/Purple.Generic.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    
</ResourceDictionary>

第一个样式(Blue.Generic.xaml)

<Style TargetType="{x:Type local:IconButton}" x:Key="BlueButton">
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="VerticalAlignment" Value="Bottom"/>
    <Setter Property="FlowDirection" Value="LeftToRight"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:IconButton}">
                <Grid Background="Transparent">
                    <Viewbox Height="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IconScale}">
                        <Path Name="PurplePath"
                                  Fill="{StaticResource LightBlueBrush}"
                                  Stretch="Fill"
                                  Data="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IconPath}"/>
                    </Viewbox>
                </Grid>
                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="MouseEnter">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
                                        <LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource Blue}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="MouseLeave">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
                                        <LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource LightBlue}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="PreviewMouseLeftButtonDown">
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
                                    <LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource DeepBlue}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="PreviewMouseLeftButtonUp">
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
                                    <LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource Blue}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

第二种样式(绿色.通用.xaml)

<Style TargetType="{x:Type local:IconButton}" x:Key="GreenButton">
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="VerticalAlignment" Value="Bottom"/>
    <Setter Property="FlowDirection" Value="LeftToRight"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:IconButton}">
                <Grid Background="Transparent">
                    <Viewbox Height="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IconScale}">
                        <Path Name="PurplePath"
                                  Fill="{StaticResource LightGreenBrush}" 
                                  Stretch="Fill"
                                  Data="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IconPath}"/>
                    </Viewbox>
                </Grid>
                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="MouseEnter">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
                                        <LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource Green}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="MouseLeave">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
                                        <LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource LightGreen}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="PreviewMouseLeftButtonDown">
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
                                    <LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource DeepGreen}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="PreviewMouseLeftButtonUp">
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
                                    <LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource Green}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

等等...

IconButton.cs

public class IconButton : Button
{
    #region Constructor

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

    #endregion Constructor

    #region Dependency Properties

    public static readonly DependencyProperty IconScaleProperty =
        DependencyProperty.Register(nameof(IconScale), typeof(double), typeof(IconButton), 
            new FrameworkPropertyMetadata(10.0));

    public static readonly DependencyProperty IconPathProperty =
        DependencyProperty.Register(nameof(IconScale), typeof(Geometry), typeof(IconButton));

    public static readonly DependencyProperty ButtonStyleProperty =
        DependencyProperty.Register(nameof(IconScale), typeof(Style), typeof(IconButton));

    #endregion Dependency Properties

    #region Properties

    public double IconScale
    {
        get => (double)GetValue(IconScaleProperty);
        set => SetValue(IconScaleProperty, value);
    }

    public Geometry IconPath
    {
        get => (Geometry)GetValue(IconPathProperty);
        set => SetValue(IconPathProperty, value);
    }

    public Style ButtonStyle
    {
        get => (Style)GetValue(ButtonStyleProperty);
        set => SetValue(ButtonStyleProperty, value);
    }

    #endregion Properties
}

有一种方法可以做这样的事情:<IconButtonControl:IconButton IconButtonStyle = "GreenButton">

fkaflof6

fkaflof61#

你可以添加一个dependency propertyIconButtonControl,并在控件的模板中绑定到它:

<ControlTemplate TargetType="{x:Type IconButtonControl}">
...
    <IconButton Style="{Binding IconButtonStyle, 
        RelativeSource={RelativeSource AncestorType=local:IconButtonControl}}" />

相关问题