【问题标题】:Switch on animation on Image from ViewModel从 ViewModel 打开 Image 上的动画
【发布时间】:2012-07-03 20:46:05
【问题描述】:

在图像上运行动画后 我从这里得到的:Animate image in a button 我希望能够打开和关闭动画,具体取决于 从外部点击按钮,即从 ViewModel

所以我在 Bahavior 中添加了一个新的 DependencyProperty(这里需要的所有东西)

 public static readonly DependencyProperty IsShakingProperty =
        DependencyProperty.Register(IsShakingName,
                                    typeof(bool),
                                    typeof(ShakeBehavior),
                                    new PropertyMetadata(DefaultIsShaking));

我已向我的 ViewModel 添加了一个新的公共属性

public bool IsShaking { get; set; }

但是我可以做些什么来打开和关闭动画,这取决于 ViewModel 属性设置为 true 还是 false? (我想控制动画 点击按钮)

这是我认为相关的一些代码

private Timeline CreateAnimationTimeline()
{
    DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();

    animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(0).(1)", UIElement.RenderTransformProperty, RotateTransform.AngleProperty));

    int keyFrameCount = 8;
    double timeOffsetInSeconds = 0.25;
    double totalAnimationLength = keyFrameCount * timeOffsetInSeconds;
    double repeatInterval = RepeatInterval;
    bool isShaking = IsShaking;

    // Can't be less than zero and pointless to be less than total length
    if (repeatInterval < totalAnimationLength)
        repeatInterval = totalAnimationLength;

    animation.Duration = new Duration(TimeSpan.FromSeconds(repeatInterval));

    int targetValue = 12;
    for (int i = 0; i < keyFrameCount; i++)
        animation.KeyFrames.Add(new LinearDoubleKeyFrame(i % 2 == 0 ? targetValue : -targetValue, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(i * timeOffsetInSeconds))));

    animation.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(totalAnimationLength))));
    return animation;
}

这是我的 XAML 的一部分:

<ListBox.ItemTemplate>
                <DataTemplate>
                    <Button Focusable="False" Command="{Binding ClickToolCommand}" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Col}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
                        <Image Source="myImage.png" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Col}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
                            <i:Interaction.Behaviors>
                                <local:ShakeBehavior RepeatInterval="1" SpeedRatio="3.0" IsShaking="{Binding Path=IsShaking}"/>
                            </i:Interaction.Behaviors>

                        </Image>
                    </Button>
                </DataTemplate>
            </ListBox.ItemTemplate>

也许 DataTrigger 可以提供帮助,正如其他 SO 中指出的那样,但我的 XAML 中没有情节提要,因为我有一个自定义 Behavior

任何意见都非常感谢!

【问题讨论】:

    标签: c# wpf xaml animation mvvm


    【解决方案1】:

    首先,让我重复一下我在最初的post 中所说的话,这就是整个事情的开始。如果您只使用自定义控件,则制作“摇晃”的图像按钮会变得简单得多。此外,使用摇摇欲坠的图像按钮作为“吸引用户注意力的一种方式”是一个可怕的想法,让我想起了 1990 年的网站设计。此外,您复制的实现中存在一个小缺陷,在创建的触发器上没有退出操作。无论如何,这里是如何做你需要的:

    如下创建附加属性:

            public static bool GetStopAnimating(DependencyObject obj)
            {
                return (bool)obj.GetValue(StopAnimatingProperty);
            }
    
            public static void SetStopAnimating(DependencyObject obj, bool value)
            {
                obj.SetValue(StopAnimatingProperty, value);
            }
    
            // Using a DependencyProperty as the backing store for StopAnimating.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty StopAnimatingProperty =
                DependencyProperty.RegisterAttached("StopAnimating", typeof(bool), typeof(ShakeBehavior), new UIPropertyMetadata(true));
    

    然后将现有的“OnAttach”方法替换为以下内容:

            private BeginStoryboard _beginStoryBoard;
            private RemoveStoryboard _removeStoryboard;
    
            protected override void OnAttached()
            {
                _orignalStyle = AssociatedObject.Style;
    
                _beginStoryBoard = new BeginStoryboard { Storyboard = CreateStoryboard() };
                _beginStoryBoard.Name = "terribleUi";
                _removeStoryboard = new RemoveStoryboard();
                _removeStoryboard.BeginStoryboardName = _beginStoryBoard.Name; 
    
                AssociatedObject.Style = CreateShakeStyle();
    
                AssociatedObject.Style.RegisterName("terribleUi", _beginStoryBoard);
            }
    

    然后,不要根据按钮的可见性来使用摇动触发器,而是将其更改为使用您的附加属性:

            private Trigger CreateTrigger()
            {
                Trigger trigger = new Trigger
                {
                    Property = StopAnimatingProperty,
                    Value = false,
                };
    
                trigger.EnterActions.Add(_beginStoryBoard);
    
                trigger.ExitActions.Add(_removeStoryboard);
    
                return trigger;
            }
    

    那你按如下方式使用:

    <Button Height="50" Width="150" >
            <StackPanel>
                <Image Source="\Untitled.png" local:ShakeBehavior.StopAnimating="{Binding YourPropertyToStopTheShaking}">
                    <i:Interaction.Behaviors>
                            <local:ShakeBehavior RepeatInterval="5.0" SpeedRatio="3.0"  />
                    </i:Interaction.Behaviors>
                </Image>
    
            </StackPanel>
        </Button>
    

    【讨论】:

    • 非常感谢!会试试这个。
    • 但是还有一些问题:你有 iPhone 吗?你会推荐什么来突出一个元素?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    相关资源
    最近更新 更多