在 ResourceDictionary 中触发的 WPF 样式应用于所有实例?

WPF style triggered in ResourceDictionary applied to all instances?

在我的 WPF 项目中,我为我的 Button 定义了一个自定义样式,键为 'MainButton_1'。
该样式在 ControlTemplate 中包含一个 MouseEnter EventTrigger,当鼠标悬停在按钮上方时,它会为按钮提供较暗的背景。

当样式存储在 App.xaml (图像的左侧部分).
时效果很好 最近我将样式移动到 ResourceDictionary AppUIResource.xaml 有趣的部分来了:当其中一个按钮悬停时,此样式上的所有按钮都会获得较暗的背景 (图片右侧).

有没有人遇到过类似的问题?有什么线索吗? :)
作为参考,我已经发布了我的 MainWindow.xamlAppUIResource.xaml(ResourceDictionary),这是问题似乎发生的时候。

如果您想查看样式何时按预期正常工作(仅触发悬停的实例),只需将样式从 AppUIResource.xaml 剪切并粘贴到 App.xaml

MainWindow.xaml

<Window x:Class="todelete_buttonTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:todelete_buttonTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="AppUIResource.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <StackPanel.Resources>
                <Style TargetType="Button" BasedOn="{StaticResource MainButton_1}">
                    <Setter Property="Height" Value="30"/>
                    <Setter Property="Width" Value="100"/>
                    <Setter Property="Margin" Value="20"/>
                </Style>
            </StackPanel.Resources>
            <Button Content="BUTTON 1"/>
            <Button Content="BUTTON 2"/>
            <Button Content="BUTTON 3"/>
        </StackPanel>
    </Grid>
</Window>

AppUIResource.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:todelete_buttonTest">
    
    <!--#region COLOR & BRUSH-->
    <Color x:Key="ThemeAccent1">#33cccc</Color>
    <SolidColorBrush x:Key="ThemeAccent1Brush" Color="{StaticResource ThemeAccent1}"/>

    <Color x:Key="ThemeAccent2">#b7eded</Color>
    <SolidColorBrush x:Key="ThemeAccent2Brush" Color="{StaticResource ThemeAccent2}"/>
    <!--#endregion Brushes-->

    <Style x:Key="MainButton_1" TargetType="{x:Type Button}" >
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Foreground" Value="{StaticResource ThemeAccent1Brush}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ThemeAccent1Brush}"/>
        <Setter Property="FontWeight" Value="Medium"/>
        <Setter Property="Margin" Value="0"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ButtonBase}">

                    <Grid>
                        <Label x:Name="label"
                               Content="{TemplateBinding Content}"
                               Focusable="False"
                               FontFamily="{TemplateBinding FontFamily}"
                               Foreground="{TemplateBinding Foreground}"
                               HorizontalAlignment="Center"
                               HorizontalContentAlignment="Center"
                               VerticalAlignment="Center"
                               VerticalContentAlignment="Center"
                               Margin="10,0,10,0"
                               Padding="0,0,0,0"
                               Panel.ZIndex="2"
                               SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        <Border x:Name="border_background"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                CornerRadius="5"
                                BorderThickness="0"
                                Background="{StaticResource ThemeAccent2Brush}"
                                Opacity="0.3"
                                SnapsToDevicePixels="True"/>
                    </Grid>
                    <!--Event triggers for styled animation-->
                    <ControlTemplate.Triggers>

                        <Trigger Property="IsEnabled" Value="false">
                            <Setter TargetName="border_background" Property="Background" Value="Transparent"/>
                            <Setter Property="Foreground" Value="LightGray"/>
                        </Trigger>

                        <EventTrigger RoutedEvent="MouseEnter">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation To="{StaticResource ThemeAccent1}"
                                                    Duration="0:0:0:0.3"
                                                    Storyboard.TargetName="border_background"
                                                    Storyboard.TargetProperty="Background.Color" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>

                        <EventTrigger RoutedEvent="MouseLeave">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation To="{StaticResource ThemeAccent2}"
                                                    Duration="0:0:0:0.3"
                                                    Storyboard.TargetName="border_background"
                                                    Storyboard.TargetProperty="Background.Color" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>

                        <EventTrigger RoutedEvent="Click">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation To="White"
                                                    Duration="0:0:0:0.1"
                                                    Storyboard.TargetName="label"
                                                    Storyboard.TargetProperty="Foreground.Color" 
                                                    AutoReverse="True"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </ControlTemplate.Triggers>

                </ControlTemplate>
            </Setter.Value>
        </Setter>

    </Style>
</ResourceDictionary>

我有两种解决方案。

1。将 AppUIResource.xaml 合并到 App.xaml.

  • MainWindow.xaml

<Window x:Class="todelete_buttonTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:todelete_buttonTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <StackPanel.Resources>
                <Style TargetType="Button" BasedOn="{StaticResource MainButton_1}">
                    <Setter Property="Height" Value="30"/>
                    <Setter Property="Width" Value="100"/>
                    <Setter Property="Margin" Value="20"/>
                </Style>
            </StackPanel.Resources>
            <Button Content="BUTTON 1"/>
            <Button Content="BUTTON 2"/>
            <Button Content="BUTTON 3"/>
        </StackPanel>
    </Grid>
</Window>
  • App.xaml

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="AppUIResource.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

2。设置 Background 的 'MainButton_1'

  • AppUIResource.xaml

<Style x:Key="MainButton_1" TargetType="{x:Type Button}" >
    <!--Set the Background-->
    <Setter Property="Background" Value="{StaticResource ThemeAccent2Brush}"/>
    ...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    ...
                    <!--TemplateBinding Background-->
                    <Border x:Name="border_background"
                            Background="{TemplateBinding Background}"
                            .../>
                    ...
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

此外,

你已经定义了MouseEnterMouseLeaveEventTrigger,但是定义IsMouseOverTrigger也是一样的效果。因为当MouseEnterMouseLeave事件发生时,IsMouseOver属性内部发生变化。所以你可以试试下面的代码!

<!--Event triggers for styled animation-->
<ControlTemplate.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation To="{StaticResource ThemeAccent1}"
                                    Duration="0:0:0:0.3"
                                    Storyboard.TargetName="border_background"
                                    Storyboard.TargetProperty="Background.Color" />
                </Storyboard>
            </BeginStoryboard>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation To="{StaticResource ThemeAccent2}"
                        Duration="0:0:0:0.3"
                        Storyboard.TargetName="border_background"
                        Storyboard.TargetProperty="Background.Color" />
                </Storyboard>
            </BeginStoryboard>
        </Trigger.ExitActions>
    </Trigger>
...