在WPF中选择“基于条件的情节提要”

本文关键字:条件 选择 WPF 于条件 | 更新日期: 2023-09-27 18:00:08

我有一个Border控件,当鼠标点击它时,如果视图模型中的"IsLeft"属性为true,我希望Border的背景立即变为绿色。如果"IsLeft"为false,我希望背景立即变为红色。

我有一个用于绿色动画的情节板,还有一个用于红色动画的第二个情节板。

我想我需要将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>

在WPF中选择“基于条件的情节提要”

您可以使用单个Storyboard,但将DiscreteColorKeyFrame.Value DependencyProperty绑定到IsLeft属性,然后使用IValueConverter将值转换为适当的颜色,而不是动态选择Storyboard

转换器看起来像这样:

[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>