在 ResourceDictionary 中触发的 WPF 样式应用于所有实例?
WPF style triggered in ResourceDictionary applied to all instances?
在我的 WPF 项目中,我为我的 Button
定义了一个自定义样式,键为 'MainButton_1'。
该样式在 ControlTemplate
中包含一个 MouseEnter
EventTrigger,当鼠标悬停在按钮上方时,它会为按钮提供较暗的背景。
当样式存储在 App.xaml
(图像的左侧部分).
时效果很好
最近我将样式移动到 ResourceDictionary AppUIResource.xaml
有趣的部分来了:当其中一个按钮悬停时,此样式上的所有按钮都会获得较暗的背景 (图片右侧).
有没有人遇到过类似的问题?有什么线索吗? :)
作为参考,我已经发布了我的 MainWindow.xaml
和 AppUIResource.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>
此外,
你已经定义了MouseEnter
、MouseLeave
EventTrigger,但是定义IsMouseOver
Trigger也是一样的效果。因为当MouseEnter
、MouseLeave
事件发生时,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>
...
在我的 WPF 项目中,我为我的 Button
定义了一个自定义样式,键为 'MainButton_1'。
该样式在 ControlTemplate
中包含一个 MouseEnter
EventTrigger,当鼠标悬停在按钮上方时,它会为按钮提供较暗的背景。
App.xaml
(图像的左侧部分).
时效果很好
最近我将样式移动到 ResourceDictionary AppUIResource.xaml
有趣的部分来了:当其中一个按钮悬停时,此样式上的所有按钮都会获得较暗的背景 (图片右侧).
有没有人遇到过类似的问题?有什么线索吗? :)
作为参考,我已经发布了我的 MainWindow.xaml
和 AppUIResource.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>
此外,
你已经定义了MouseEnter
、MouseLeave
EventTrigger,但是定义IsMouseOver
Trigger也是一样的效果。因为当MouseEnter
、MouseLeave
事件发生时,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>
...