繁体   English   中英

故事板未触发的数据触发

[英]Datatrigger with Storyboard not firing

我在同一Image上有5个不同的DataTriggers,每个DataTriggers用于相同的Binding,但具有不同的Value,它们分别将Image旋转不同的角度。 每次更改值后,该值都将重置为0。

当我没有添加DataTrigger.ExitActions> <RemoveStoryboard> ,它们只工作了一次,但它们只工作了一次,因此,如果Binding steps再次获得此值,它们将不会触发。

<Image x:Name="drehteller" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Source="{Binding drehteller_image}">
        <Image.RenderTransform>
            <RotateTransform/>
        </Image.RenderTransform>
        <Image.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding steps}" Value="1">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard x:Name="Storyboard1Step">
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetProperty="RenderTransform.Angle" 
                                        By="72"
                                        Duration="00:00:00:03"
                                    />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <RemoveStoryboard BeginStoryboardName="Storyboard1Step"/>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding steps}" Value="2">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard x:Name="Storyboard2Step">
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetProperty="RenderTransform.Angle" 
                                        By="144"
                                        Duration="00:00:00:03"
                                    />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <RemoveStoryboard BeginStoryboardName="Storyboard2Step"/>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding steps}" Value="3">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard x:Name="Storyboard3Step">
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetProperty="RenderTransform.Angle" 
                                        By="216"
                                        Duration="00:00:00:03"
                                    />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <RemoveStoryboard BeginStoryboardName="Storyboard3Step"/>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding steps}" Value="4">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard x:Name="Storyboard4Step">
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetProperty="RenderTransform.Angle" 
                                        By="72"
                                        Duration="00:00:00:03"
                                    />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <RemoveStoryboard BeginStoryboardName="Storyboard4Step"/>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding steps}" Value="5">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard x:Name="Storyboard5Step">
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetProperty="RenderTransform.Angle" 
                                        By="360"
                                        Duration="00:00:00:03"
                                    />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <RemoveStoryboard BeginStoryboardName="Storyboard5Step"/>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>

也许有人对我做错了什么有一个想法,我认为RemoveStoryboard可能会解决他们只触发一个问题,但看起来却没有的问题。

编辑:发现如果没有ExitActions我就可以ExitActions触发具有值1的触发器,只要该值永远不会高于1,所以如果我一次触发具有值2的触发器,则具有值1的触发器将不会不再起作用,并且如果我触发具有值3的触发器,则具有值2的触发器将不再起作用。 依此类推,猜想你明白了。

一个非常简单而直接的解决方案是在后面的代码中运行动画:

var viewModel = new ViewModel();

viewModel.PropertyChanged += (s, e) =>
{
    if (e.PropertyName == nameof(viewModel.Steps))
    {
        drehteller.RenderTransform.BeginAnimation(
            RotateTransform.AngleProperty,
            new DoubleAnimation
            {
                By = viewModel.Steps * 72,
                Duration = TimeSpan.FromSeconds(3)
            });
    }
};

DataContext = viewModel;

这与MVVM并不矛盾,因为视图模型仍然对视图一无所知。 这是一个纯粹的观点方面。

您也可以使用附加行为来执行此操作。 这些是可重用视图逻辑的一部分,您可以将它们附加到各种UI元素上,而无需将其放在后面的代码中。

您将需要Microsoft.Xaml.Behaviors.Wpf NuGet程序包 (此程序包以前是作为Visual Studio的“ .NET的Visual Studio SDK混合”组件的一部分分发的,但在VS 2019中已更改)。

定义您的行为。 请注意, AssociatedObject引用与此行为相关联的Image ,请参见下文。

public class AnimateBehavior : Behavior<Image>
{
    public int Steps
    {
        get => (int)GetValue(StepsProperty);
        set => SetValue(StepsProperty, value);
    }
    public static readonly DependencyProperty StepsProperty =
        DependencyProperty.Register(nameof(Steps), typeof(int), typeof(AnimateBehavior), new PropertyMetadata(0, (d, e) => ((AnimateBehavior)d).StepsChanged(e)));

    private void StepsChanged(DependencyPropertyChangedEventArgs e)
    {
        if (AssociatedObject == null)
            return;

        AssociatedObject.RenderTransform.BeginAnimation(
            RotateTransform.AngleProperty,
            new DoubleAnimation()
            {
                By = (int)e.NewValue * 72,
                Duration = TimeSpan.FromSeconds(3),
            });
    }
}

然后在您的XAML中,您将需要以下名称空间:

xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"

然后:

<Image ...>
    <Image.RenderTransform>
        <RotateTransform/>
    </Image.RenderTransform>
    <behaviors:Interaction.Behaviors>
        <local:AnimateBehavior Steps="{Binding steps}"/>
    </behaviors:Interaction.Behaviors>
</Image>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM