WPFのアニメーションはそれほど簡単ではなく、いくつかの理由で回避しようとします。 1つは、開始するのが難しく、停止するのが難しいということです。 第二-彼らは非常に高速ではありません。
打ち上げに対処します-とても「複雑」です。 簡単なItemsControlを描画してみましょう。その中にCanvasがあり、小さなボールが配置されています。
<ItemsControl ItemsSource="{Binding Bubbles}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas IsItemsHost="True" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style> <Setter Property="Canvas.Left" Value="{Binding X}" /> <Setter Property="Canvas.Top" Value="{Binding Y}" /> </Style> </ItemsControl.ItemContainerStyle> <ItemsControl.ItemTemplate> <DataTemplate> <Ellipse Width="10" Height="10" Fill="#FF616AB6" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
結果のデモンストレーション:
次に、それらをアニメーション化する必要があります。これのために、位置計算をCanvas.LeftとCanvas.Topからアニメーションに転送し、要素のCanvas.LeftとCanvas.Topを設定します。 各楕円のリソースに配置します。
<Ellipse.Resources> <Storyboard x:Key="yanimation"> <DoubleAnimation Storyboard.Target="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentPresenter}}" Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:1" To="{Binding Y}" /> </Storyboard> <Storyboard x:Key="xanimation"> <DoubleAnimation Storyboard.Target="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentPresenter}}" Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:1" To="{Binding X}" /> </Storyboard> </Ellipse.Resources>
しかし今、問題はアニメーションをいつ開始するかです。 間違いなく、要素が現れたときに実行する必要があります。つまり、次を追加します。
<Ellipse.Triggers> <EventTrigger RoutedEvent="Ellipse.Loaded"> <BeginStoryboard Storyboard="{StaticResource xanimation}" /> </EventTrigger> <EventTrigger RoutedEvent="Ellipse.Loaded"> <BeginStoryboard Storyboard="{StaticResource yanimation}" /> </EventTrigger> </Ellipse.Triggers>
しかし、今はどうですか? 良い方法では、アニメーションを自分で実行するようにバインドし、バインドの各NotificationOnTargetUpdated = TrueにToを追加できます。 次に書くことができます
<Ellipse.Triggers> <EventTrigger RoutedEvent="Binding.TargetUpdated"> <BeginStoryboard Storyboard="{StaticResource xanimation}" /> </EventTrigger> <EventTrigger RoutedEvent="Binding.TargetUpdated"> <BeginStoryboard Storyboard="{StaticResource yanimation}" /> </EventTrigger> </Ellipse.Triggers>
そしてそれは動作します。 しかし、それほど単純ではありません。 生きているプロジェクトでは、このアプローチは動作を拒否しました-おそらくループ呼び出しのためです。 また、NotifyOnTargetUpdated = Trueをどこでも記述でき、アニメーションが再び呼び出されます。 ただし、XプロパティとYプロパティが変更されたときにのみアニメーションを開始する必要があり、ここでライブラリSDK.Microsoft.Expression.InteractionsおよびSystem.Windows.Interactivityを使用してBlend SDKが助けになります。
それらをプロジェクトに追加します(nugetで追加しました)。 そして、必要なxmlnsを規定します。
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
これで、各Ellipse内に記述できます。
<i:Interaction.Triggers> <ei:PropertyChangedTrigger Binding="{Binding X}"> <ei:ControlStoryboardAction Storyboard="{StaticResource xanimation}" /> </ei:PropertyChangedTrigger> <ei:PropertyChangedTrigger Binding="{Binding Y}"> <ei:ControlStoryboardAction Storyboard="{StaticResource yanimation}" /> </ei:PropertyChangedTrigger> </i:Interaction.Triggers>
そしてアニメーションが始まりました:
仕事完了!
再度実行することはなく、必要に応じて機能します。 さらに、Blend SDKには、他にも多くのシンプルで同時に信じられないほど便利なものが含まれています。
Microsoft.Expression.Interactionsのドキュメント
System.Windows.Interactivityドキュメント
そして、記事の最初に戻って、2番目の点に注意を払いたいと思います。アニメーションは非常に遅いということです。 はい-彼らは私がそれをどうするかわからないほどですが、それにもかかわらず私は見つけようとします。
ご清聴ありがとうございました!
→ githubのプロジェクトへのリンク