Select WPF 中基于条件的故事板
Select Storyboard Based On Condition In WPF
我有一个 Border 控件,当鼠标单击它时,如果我的视图模型中的 "IsLeft" 属性 为真,我希望 Border 的背景立即变为绿色。如果 "IsLeft" 为假,我希望背景暂时变红。
绿色动画有一个故事板,红色动画有第二个故事板。
我想我需要组合 EventTrigger(用于鼠标单击)和 DataTrigger(绑定到 IsLeft)来执行此操作,但我不确定如何。
请注意,我还有一个 MVVM 中继命令,用于在单击边框时在 ViewModel 中执行一些逻辑。
<Window x:Class="WpfTestBase.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:WpfTestBase"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:Custom="http://www.galasoft.ch/mvvmlight"
xmlns:h="clr-namespace:WpfTestBase.Helpers"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding Path=Main, Source={StaticResource Locator}}">
<Window.Resources>
<Storyboard x:Key="StoryboardCorrect">
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsEnabled)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
</BooleanAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Duration="0:0:0.5" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<DiscreteColorKeyFrame KeyTime="0:0:0" Value="#00FF00"/>
<DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="LightBlue"/>
</ColorAnimationUsingKeyFrames>
<h:CommandFakeAnimation Duration="0:0:0" Command="{Binding Path=FakeAnimationCommand, Mode=OneWay}"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
<Storyboard x:Key="StoryboardWrong">
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsEnabled)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
</BooleanAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<DiscreteColorKeyFrame KeyTime="0:0:0" Value="#FF0000"/>
<DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="LightBlue"/>
</ColorAnimationUsingKeyFrames>
<h:CommandFakeAnimation Duration="0:0:0" Command="{Binding Path=FakeAnimationCommand, Mode=OneWay}"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</Window.Resources>
<Canvas>
<Viewbox Canvas.Left="025" Canvas.Top="57">
<Border x:Name="border" Width="200" Height="82" Canvas.Left="098" Canvas.Top="93" BorderThickness="6,8,7,8"
BorderBrush="Black" Background="LightBlue">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<Custom:EventToCommand Command="{Binding BorderCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Border.Triggers>
<EventTrigger RoutedEvent="Border.MouseLeftButtonUp">
<BeginStoryboard Storyboard="{StaticResource StoryboardCorrect}"/>
</EventTrigger>
</Border.Triggers>
<TextBlock Text="{Binding CountModel.Word}"/>
</Border>
</Viewbox>
<TextBlock x:Name="textBlock1" Canvas.Left="312" TextWrapping="Wrap" Text="IsLeft:" Canvas.Top="188"/>
<TextBlock x:Name="textBlock2" Canvas.Left="348" TextWrapping="Wrap" Text="{Binding IsLeft}" Canvas.Top="188"/>
</Canvas>
您可以使用单个 Storyboard
而不是动态选择 Storyboard
,而是将您的 DiscreteColorKeyFrame.Value
DependencyProperty 绑定到您的 IsLeft
属性 然后使用IValueConverter
将值转换为适当的颜色。
转换器看起来像这样:
[ValueConversion(typeof(bool), typeof(System.Windows.Media.Color))]
public class IsLeftToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)value) ? System.Windows.Media.Color.Green : System.Windows.Media.Color.Red
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
您的 XAML 可能看起来像这样:
<Border x:Name="border" Width="200" Height="82" Canvas.Left="098" Canvas.Top="93" BorderThickness="6,8,7,8"
BorderBrush="Black" Background="LightBlue">
<Border.Triggers>
<EventTrigger RoutedEvent="Border.MouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsEnabled)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
</BooleanAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<DiscreteColorKeyFrame KeyTime="0:0:0" Value="{Binding IsLeft, Converter={StaticResource IsLeftToColorConverter}}"/>
<DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="LightBlue"/>
</ColorAnimationUsingKeyFrames>
<h:CommandFakeAnimation Duration="0:0:0" Command="{Binding Path=FakeAnimationCommand, Mode=OneWay}"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<TextBlock Text="{Binding CountModel.Word}"/>
</Border>
我有一个 Border 控件,当鼠标单击它时,如果我的视图模型中的 "IsLeft" 属性 为真,我希望 Border 的背景立即变为绿色。如果 "IsLeft" 为假,我希望背景暂时变红。
绿色动画有一个故事板,红色动画有第二个故事板。
我想我需要组合 EventTrigger(用于鼠标单击)和 DataTrigger(绑定到 IsLeft)来执行此操作,但我不确定如何。
请注意,我还有一个 MVVM 中继命令,用于在单击边框时在 ViewModel 中执行一些逻辑。
<Window x:Class="WpfTestBase.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:WpfTestBase"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:Custom="http://www.galasoft.ch/mvvmlight"
xmlns:h="clr-namespace:WpfTestBase.Helpers"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding Path=Main, Source={StaticResource Locator}}">
<Window.Resources>
<Storyboard x:Key="StoryboardCorrect">
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsEnabled)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
</BooleanAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Duration="0:0:0.5" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<DiscreteColorKeyFrame KeyTime="0:0:0" Value="#00FF00"/>
<DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="LightBlue"/>
</ColorAnimationUsingKeyFrames>
<h:CommandFakeAnimation Duration="0:0:0" Command="{Binding Path=FakeAnimationCommand, Mode=OneWay}"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
<Storyboard x:Key="StoryboardWrong">
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsEnabled)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
</BooleanAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<DiscreteColorKeyFrame KeyTime="0:0:0" Value="#FF0000"/>
<DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="LightBlue"/>
</ColorAnimationUsingKeyFrames>
<h:CommandFakeAnimation Duration="0:0:0" Command="{Binding Path=FakeAnimationCommand, Mode=OneWay}"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</Window.Resources>
<Canvas>
<Viewbox Canvas.Left="025" Canvas.Top="57">
<Border x:Name="border" Width="200" Height="82" Canvas.Left="098" Canvas.Top="93" BorderThickness="6,8,7,8"
BorderBrush="Black" Background="LightBlue">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<Custom:EventToCommand Command="{Binding BorderCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Border.Triggers>
<EventTrigger RoutedEvent="Border.MouseLeftButtonUp">
<BeginStoryboard Storyboard="{StaticResource StoryboardCorrect}"/>
</EventTrigger>
</Border.Triggers>
<TextBlock Text="{Binding CountModel.Word}"/>
</Border>
</Viewbox>
<TextBlock x:Name="textBlock1" Canvas.Left="312" TextWrapping="Wrap" Text="IsLeft:" Canvas.Top="188"/>
<TextBlock x:Name="textBlock2" Canvas.Left="348" TextWrapping="Wrap" Text="{Binding IsLeft}" Canvas.Top="188"/>
</Canvas>
您可以使用单个 Storyboard
而不是动态选择 Storyboard
,而是将您的 DiscreteColorKeyFrame.Value
DependencyProperty 绑定到您的 IsLeft
属性 然后使用IValueConverter
将值转换为适当的颜色。
转换器看起来像这样:
[ValueConversion(typeof(bool), typeof(System.Windows.Media.Color))]
public class IsLeftToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)value) ? System.Windows.Media.Color.Green : System.Windows.Media.Color.Red
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
您的 XAML 可能看起来像这样:
<Border x:Name="border" Width="200" Height="82" Canvas.Left="098" Canvas.Top="93" BorderThickness="6,8,7,8"
BorderBrush="Black" Background="LightBlue">
<Border.Triggers>
<EventTrigger RoutedEvent="Border.MouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsEnabled)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
<DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
</BooleanAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<DiscreteColorKeyFrame KeyTime="0:0:0" Value="{Binding IsLeft, Converter={StaticResource IsLeftToColorConverter}}"/>
<DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="LightBlue"/>
</ColorAnimationUsingKeyFrames>
<h:CommandFakeAnimation Duration="0:0:0" Command="{Binding Path=FakeAnimationCommand, Mode=OneWay}"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<TextBlock Text="{Binding CountModel.Word}"/>
</Border>