0

ここから取得した画像のアニメーションを実行した後:ボタンで画像を アニメーション化する外部、つまりViewModelからのボタンのクリックに応じて、アニメーションのオンとオフを切り替えられるようにしたい

そこで、新しいDependencyPropertyをBahaviorに追加しました(ここで必要なものはすべて)

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

ViewModelに新しいパブリックプロパティを追加しました

public bool IsShaking { get; set; }

しかし、Trueまたはfalseに設定されたViewModelプロパティに応じて、アニメーションのオンとオフを切り替えるにはどうすればよいですか?(ボタンクリックでアニメーションを制御したい)

これが私が関連すると思うコードのいくつかです

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>

他のSOで指摘されているように、おそらくDataTriggerが役立つ可能性がありますが、カスタムがあるため、XAML内にストーリーボードがありません。Behavior

どんな入力でも大歓迎です!

4

1 に答える 1

0

最初に、このすべての始まりとなった元の投稿で私が言ったことを繰り返しさせてください。カスタムコントロールを使用するだけで、「揺れる」画像ボタンを作成するのがずっと簡単になります。また、揺れる画像ボタンを「ユーザーの注意を引く方法」として使用することは、1990 年代の Web サイト デザインを思い起こさせる恐ろしい考えです。さらに、コピーした実装には小さな欠陥があり、作成されたトリガーには終了アクションがありません。とにかく、必要なことを行う方法は次のとおりです。

次のように添付プロパティを作成します。

        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>
于 2012-07-04T23:44:05.687 に答える