x:NameもしくはFindNameの怪 その1
ストーリーボードでスケールを伸ばした後に、コードで戻そうとしたときにへんな挙動が・・・。
Rectangle を伸ばす Storyboardを書こう!
まずは Rectangle を置きます。で、それのスケールを Storyboard で伸ばします。
こんな感じ。
<Storyboard x:Name="Storyboard1"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="20"/> </DoubleAnimationUsingKeyFrames> </Storyboard> ・・・・・・ <Rectangle Width="15" Fill="#FFFF0000" x:Name="rectangle"> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle>
作ったストーリーボードを動かすボタンも置きます。で、そのクリックイベントでストーリーボードを起動します。
<Button Content="伸ばす" Click="Button_Click"/>
private void Button_Click(object sender, RoutedEventArgs e) { Storyboard1.Begin(); }
で、実行してボタンをクリックすると無事にストーリーボードが動いて、幅が伸びるわけです。
幅を元に戻してみよう!
次に、幅を元に戻します。これはストーリーボードではなくコードで直接プロパティに値を設定します。戻す用のボタンをもう一つ追加して、クリックイベントの中で、プロパティを設定します。
<Button Content="戻す" Click="Button_Click_1" />
private void Button_Click_1(object sender, RoutedEventArgs e) { ((rectangle.RenderTransform as TransformGroup).Children[0] as ScaleTransform).ScaleX = 1d; }
いろんなことを無視しまくっているコードはご愛敬ってことで。
戻りました?戻りましたよね。
ScaleTransformに名前を付けてみよう!
スケールを元に戻すコードが長くってめんどくさいので ScaleTransformに名前を付けてそれを使うようにします。
<Rectangle Width="15" Fill="#FFFF0000" x:Name="rectangle"> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform x:Name="scale"/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle>
private void Button_Click_1(object sender, RoutedEventArgs e) { scale.ScaleX = 1d; //((rectangle.RenderTransform as TransformGroup).Children[0] as ScaleTransform).ScaleX = 1d; }
実行してみてください。戻りました?戻りました?戻らないですよね?
そうです。謎なんです。戻らないんです。
Storyboardのターゲット指定を変えてみよう!
戻らないのでかなり謎なのですが仕方ないので、Storyboardのターゲット指定を変えてみます。
<Storyboard x:Name="Storyboard1"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX"> <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="20"/> </DoubleAnimationUsingKeyFrames> </Storyboard>
実行してみてください。戻りました?戻りました?戻りましたよね?
そうです。謎なんです。戻ってしまうんです。
そんなこんなで、これに今日2時間近くはまっちまいました。
悔しいのでもうちょっと調べてみます。
インスタンスが同じか見てみよう!!
まぁ、間違いなく同じだとは思うのですが、、、
private void Button_Click_1(object sender, RoutedEventArgs e) { MessageBox.Show(scale.Equals((rectangle.RenderTransform as TransformGroup).Children[0] as ScaleTransform).ToString()); //scale.ScaleX = 1d; //((rectangle.RenderTransform as TransformGroup).Children[0] as ScaleTransform).ScaleX = 1d;
手抜きなのはご愛敬ってことで。
で、やっぱり "true" って表示されます。そりゃそうか。
依存関係プロパティで設定してみよう!!
ストーリボードのXAMLは最初のものに戻しておいてください。
<Storyboard x:Name="Storyboard1"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="20"/> </DoubleAnimationUsingKeyFrames> </Storyboard>
戻すコード側を依存関係プロパティで設定するようにしてみましょう。
private void Button_Click_1(object sender, RoutedEventArgs e) { scale.SetValue(ScaleTransform.ScaleXProperty,1d); //scale.ScaleX = 1d; //((rectangle.RenderTransform as TransformGroup).Children[0] as ScaleTransform).ScaleX = 1d; }
やっぱり動きません・・・。
RenderTransformにScaleTransformを直接設定してみよう!!
BlendでRenderTransform系を設定するとTransformGroupが作られるのですが、RenderTransformに直接ScaleTransformを指定してみます。
<Rectangle Fill="#FFFF0000" x:Name="rectangle"> <Rectangle.RenderTransform> <ScaleTransform x:Name="scale"/> </Rectangle.RenderTransform> </Rectangle>
ストーリーボードは下。
<Storyboard x:Name="Storyboard1"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"> <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="20"/> </DoubleAnimationUsingKeyFrames> </Storyboard>
気を取り直して C# も元に戻します。
private void Button_Click_1(object sender, RoutedEventArgs e) { scale.ScaleX = 1d; //((rectangle.RenderTransform as TransformGroup).Children[0] as ScaleTransform).ScaleX = 1d; }
やっぱり動きません。。。orz
仕方がないので、rectangleから指定してみます。
private void Button_Click_1(object sender, RoutedEventArgs e) { //scale.ScaleX = 1d; (rectangle.RenderTransform as ScaleTransform).ScaleX = 1; }
いやー、腹立たしいくらい予想通りに元に戻ってくれますね!
疲れてきたので謎は謎のままにしておくってことで。。