[WinRT] Gridに貼り付けたコントロールの絶対座標を取得する | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/4062
の続きです。この絶対座標を使ってアニメーションさせれば ok っだね、ってことで先に絶対座標を計算いたのですが、実はアニメーション自体は「相対座標」になるので、この手の Margin のややこしい計算は必要がなかったんですよね~、というオチです。
条件としては、適当に移動コントロールを用意しておいて、適当な開始位置から適当な終了位置までにアニメーションします。
アニメーション自体は、Blend を使って大体の位置で作成しておきます。「大体」でよいのは、開始位置と終了位置はプログラムのほうで制御するためです。
<Page.Resources> <Storyboard x:Name="sbMove1"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="pict1"> <EasingDoubleKeyFrame x:Name="startPosX" KeyTime="0" Value="405.97"/> <EasingDoubleKeyFrame x:Name="endPosX" KeyTime="0:0:3" Value="441.791"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="pict1"> <EasingDoubleKeyFrame x:Name="startPosY" KeyTime="0" Value="277.612"/> <EasingDoubleKeyFrame x:Name="endPosY" KeyTime="0:0:3" Value="-11.941"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </Page.Resources>
あらかじめ作った storyboard に対して変更部分に名前をつけていきます。開始位置(startPosX,startPosY) と終了位置(endPosX,endPosY) だけで ok です。アニメーションする時間を変更したい場合は、endPosX.KeyTime, endPosY.KeyTime で指定できるので汎用的に使えます。
■アニメーションを開始する
これを使ってアニメーションさせるのが次のコードです。
private void Button3Click(object sender, RoutedEventArgs e) { // 移動対象の絶対座標 var pt1 = _pt1; // 開始位置の絶対座標 var pt2 = pict2.TransformToVisual(null).TransformPoint(new Point(0, 0)); // 終了位置の絶対座標 var pt3 = pict3.TransformToVisual(null).TransformPoint(new Point(0, 0)); // 開始、終了位置を相対座標で設定 startPosX.Value = pt2.X - pt1.X; startPosY.Value = pt2.Y - pt1.Y; endPosX.Value = pt3.X - pt1.X; endPosY.Value = pt3.Y - pt1.Y; // アニメーション開始 sbMove1.Begin(); sbMove1.Completed += (_, __) => { ; }; }
startPosX.Value に設定するのは、相対座標なので、pt2.X – pt1.X になります。元の pt1 を取っておかないとダメなのがちょっとダサいですが、移動用のコントロールの座標を(0,0)にして左上にしておけば、pt1 の値はいりません。
アニメーションの終了は、Completed イベントで拾えるので、ラムダ式で設定しておくとコードが簡単になるかと。移動用のコントロールを消すとか、元の位置に戻すとかを、
sbMove1.Completed += (_, __) => { sbMove1.Stop(); grid1.Visibility = Windows.UI.Xaml.Visibility.Collapsed; };
のようにしておくとよいかと。