none
StoryBoardに設定したBindingが初回のみ失敗する RRS feed

  • 質問

  • はじめまして。WPF初心者です。

    現在、StoryBoardとBindingの学習として、
    複数のボタンから、一つ選んでクリックすると、そのボタンのContentに表示されている値(例えば「150」)に応じて、ボタンが上下に動くというアプリを作成しています。
    クリックされたボタンはINotifyPropertyChangedが実装されたクラスに格納するようにしています。

    ただ、アプリ起動後、最初のクリック時のみ、ボタンが動きません・・・。
    記述がおかしいのでしょうか?

    何かアドバイスを頂けませんか? よろしくお願い致します。
    -----
    [XAML]
    <Window.Resources>
      <Storyboard x:Key="myStory">
                <DoubleAnimationUsingKeyFrames
              BeginTime="00:00:00" Storyboard.TargetName="{Binding Path=TargetButton.Name}"  
              Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                      <SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="{Binding Path=TargetButton.Content}"/>
                </DoubleAnimationUsingKeyFrames>
      </Storyboard>
    </Window.Resources>

    <Grid x:Name="LayoutRoot">
      <Button x:Name="Button1" Content="150" Click="Button_Click"  />
      <Button x:Name="Button2" Content="200" Margin="200,200,0,0"  Click="Button_Click" />
      <Button x:Name="Button3" Content="210" Margin="350,200,0,0"  Click="Button_Click" />
    </Grid>

    [C#]
    public Window1()
    {
        this.InitializeComponent();
       this.DataContext = new BindingClass1();
     }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        ((BindingClass1)this.DataContext).TargetButton = target;  
         BeginStoryboard(this.Resources["myStory"] as System.Windows.Media.Animation.Storyboard);
     }
    --------

    2009年8月25日 7:48

回答

  • こんにちは。

    初回のみ失敗するとの事ですが、その前に書かれているソース自体が実行出来ません。
    コードを乗せるのであれば最低限動作が確認出来るような物を書かれた方が宜しいかと思います。

    それとパッと見た感じ、Button_Clickイベントハンドラ内のBeginStoryboardメソッドはWindowのBeginStoryboardメソッドを呼んでいますよ?
    Buttonコントロールをアニメーションさせたいのですよね?

    kazuto Blog : http://blogs.wankuma.com/kzt/
    • 回答としてマーク _kiyo 2009年8月31日 4:36
    • 回答としてマークされていない _kiyo 2009年8月31日 4:36
    • 回答としてマーク 高橋 春樹 2009年8月31日 6:14
    2009年8月26日 5:54
  • 和人さん

    レスポンス&アドバイスありがとうございます。
    投稿時、ゴミと一緒に必要な部分も消去したソースを載せてしまっていました。
    大変失礼しました。

    アドバイスを受けて、再度見直した所、問題を解決することができました。

    >それとパッと見た感じ、Button_Clickイベントハンドラ内のBeginStoryboardメソッドはWindowのBeginStoryboardメソッドを呼んでいますよ?
    >Buttonコントロールをアニメーションさせたいのですよね?

    はい。クリックされたボタンをクラスに格納してから、StoryBoardを動かしたいと思ったのでこのような記述にしていました。
    試しにWindow.TriggersでBeginStoryboardを呼ぶよう変更すると、思い通りの動作を実現することができました。
    ただ、なぜC#側でBeginStoryboardを呼んだ時と動作が異なるのかが、まだよく分かっていないため勉強します。


    長いですが・・・コード全文を投稿させていただきます。
    -----
    [XAML]
    <Window
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     x:Class="BindingSample.Window1"
     x:Name="Window"
     Title="StoryBoard_And_Binding"
     Width="640" Height="480" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
     <Window.Resources>
      <Style TargetType="{x:Type Button}">
       <Setter Property="Width" Value="150"/>
       <Setter Property="Height" Value="50"/>
                <Setter Property="Focusable" Value="False"/>
       <Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
       <Setter Property="RenderTransform">
                    <Setter.Value>
                        <TransformGroup>
                            <ScaleTransform ScaleX="1" ScaleY="1"/>
                            <SkewTransform AngleX="0" AngleY="0"/>
                            <RotateTransform Angle="0"/>
                            <TranslateTransform X="0" Y="0"/>
                        </TransformGroup>
                    </Setter.Value>
                </Setter>
      </Style>
      <Storyboard x:Key="myStory">
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="{Binding Path=TargetButton.Name}" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" AutoReverse="True">
                    <SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="{Binding Path=TargetButton.Content}"/>
                </DoubleAnimationUsingKeyFrames>
      </Storyboard>
     </Window.Resources>
     <Window.Triggers>
      <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="Button1">
       <BeginStoryboard Storyboard="{StaticResource myStory}"/>
      </EventTrigger>
      <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="Button2">
       <BeginStoryboard Storyboard="{StaticResource myStory}"/>
      </EventTrigger>
      <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="Button3">
       <BeginStoryboard Storyboard="{StaticResource myStory}"/>
      </EventTrigger>
     </Window.Triggers>
        
     <Grid x:Name="LayoutRoot">
      <Button HorizontalAlignment="Left" VerticalAlignment="Top" Content="150" x:Name="Button1" Margin="50,0,0,0"  Click="Button_Click"/>
      <Button HorizontalAlignment="Left" VerticalAlignment="Top" Content="200" x:Name="Button2" Margin="240,0,0,0" Click="Button_Click"/>
      <Button HorizontalAlignment="Right" VerticalAlignment="Top" Content="210" x:Name="Button3"  Margin="0,0,50,0" Click="Button_Click"/>
     </Grid>
    </Window>

    ****
    [C#]
     public partial class Window1 : Window
     {
      public Window1()
      {
       this.InitializeComponent();
                // オブジェクト作成に必要なコードをこの点の下に挿入します。
                this.DataContext = new BindingClass1();
      }
     private void Button_Click(object sender, RoutedEventArgs e)
      {
                ((BindingClass1)this.DataContext).TargetButton = (Button)e.Source;
                //BeginStoryboard(this.Resources["myStory"] as System.Windows.Media.Animation.Storyboard);
       }
     }

    **** BindingClass
        public class BindingClass1 : INotifyPropertyChanged
        {
            #region INotifyPropertyChanged メンバ
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
           
            #endregion
            private Button _targetbutton;
            public Button TargetButton
            {
                get { return _targetbutton; }
                set
                {
                    _targetbutton = value;
                    OnPropertyChanged("TargetButton");
                }
            }
         }
    -------

    • 回答としてマーク _kiyo 2009年8月31日 4:36
    2009年8月31日 4:30

すべての返信

  • こんにちは。

    初回のみ失敗するとの事ですが、その前に書かれているソース自体が実行出来ません。
    コードを乗せるのであれば最低限動作が確認出来るような物を書かれた方が宜しいかと思います。

    それとパッと見た感じ、Button_Clickイベントハンドラ内のBeginStoryboardメソッドはWindowのBeginStoryboardメソッドを呼んでいますよ?
    Buttonコントロールをアニメーションさせたいのですよね?

    kazuto Blog : http://blogs.wankuma.com/kzt/
    • 回答としてマーク _kiyo 2009年8月31日 4:36
    • 回答としてマークされていない _kiyo 2009年8月31日 4:36
    • 回答としてマーク 高橋 春樹 2009年8月31日 6:14
    2009年8月26日 5:54
  • 和人さん

    レスポンス&アドバイスありがとうございます。
    投稿時、ゴミと一緒に必要な部分も消去したソースを載せてしまっていました。
    大変失礼しました。

    アドバイスを受けて、再度見直した所、問題を解決することができました。

    >それとパッと見た感じ、Button_Clickイベントハンドラ内のBeginStoryboardメソッドはWindowのBeginStoryboardメソッドを呼んでいますよ?
    >Buttonコントロールをアニメーションさせたいのですよね?

    はい。クリックされたボタンをクラスに格納してから、StoryBoardを動かしたいと思ったのでこのような記述にしていました。
    試しにWindow.TriggersでBeginStoryboardを呼ぶよう変更すると、思い通りの動作を実現することができました。
    ただ、なぜC#側でBeginStoryboardを呼んだ時と動作が異なるのかが、まだよく分かっていないため勉強します。


    長いですが・・・コード全文を投稿させていただきます。
    -----
    [XAML]
    <Window
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     x:Class="BindingSample.Window1"
     x:Name="Window"
     Title="StoryBoard_And_Binding"
     Width="640" Height="480" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
     <Window.Resources>
      <Style TargetType="{x:Type Button}">
       <Setter Property="Width" Value="150"/>
       <Setter Property="Height" Value="50"/>
                <Setter Property="Focusable" Value="False"/>
       <Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
       <Setter Property="RenderTransform">
                    <Setter.Value>
                        <TransformGroup>
                            <ScaleTransform ScaleX="1" ScaleY="1"/>
                            <SkewTransform AngleX="0" AngleY="0"/>
                            <RotateTransform Angle="0"/>
                            <TranslateTransform X="0" Y="0"/>
                        </TransformGroup>
                    </Setter.Value>
                </Setter>
      </Style>
      <Storyboard x:Key="myStory">
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="{Binding Path=TargetButton.Name}" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" AutoReverse="True">
                    <SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="{Binding Path=TargetButton.Content}"/>
                </DoubleAnimationUsingKeyFrames>
      </Storyboard>
     </Window.Resources>
     <Window.Triggers>
      <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="Button1">
       <BeginStoryboard Storyboard="{StaticResource myStory}"/>
      </EventTrigger>
      <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="Button2">
       <BeginStoryboard Storyboard="{StaticResource myStory}"/>
      </EventTrigger>
      <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="Button3">
       <BeginStoryboard Storyboard="{StaticResource myStory}"/>
      </EventTrigger>
     </Window.Triggers>
        
     <Grid x:Name="LayoutRoot">
      <Button HorizontalAlignment="Left" VerticalAlignment="Top" Content="150" x:Name="Button1" Margin="50,0,0,0"  Click="Button_Click"/>
      <Button HorizontalAlignment="Left" VerticalAlignment="Top" Content="200" x:Name="Button2" Margin="240,0,0,0" Click="Button_Click"/>
      <Button HorizontalAlignment="Right" VerticalAlignment="Top" Content="210" x:Name="Button3"  Margin="0,0,50,0" Click="Button_Click"/>
     </Grid>
    </Window>

    ****
    [C#]
     public partial class Window1 : Window
     {
      public Window1()
      {
       this.InitializeComponent();
                // オブジェクト作成に必要なコードをこの点の下に挿入します。
                this.DataContext = new BindingClass1();
      }
     private void Button_Click(object sender, RoutedEventArgs e)
      {
                ((BindingClass1)this.DataContext).TargetButton = (Button)e.Source;
                //BeginStoryboard(this.Resources["myStory"] as System.Windows.Media.Animation.Storyboard);
       }
     }

    **** BindingClass
        public class BindingClass1 : INotifyPropertyChanged
        {
            #region INotifyPropertyChanged メンバ
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
           
            #endregion
            private Button _targetbutton;
            public Button TargetButton
            {
                get { return _targetbutton; }
                set
                {
                    _targetbutton = value;
                    OnPropertyChanged("TargetButton");
                }
            }
         }
    -------

    • 回答としてマーク _kiyo 2009年8月31日 4:36
    2009年8月31日 4:30
  • こんにちは、フォーラムオペレーターの高橋春樹です。

    和人さん、初めまして。
    アドバイスありがとうございました。

    _kiyoさん、初めまして。
    MSDNフォーラムのご利用ありがとうございました。
    問題が解決して良かったです。

    今回、_kiyoさんが和人さんの投稿に、回答マークを付けたにも拘わらず、
    ページ更新のタイミングの都合上、間違えて回答マークを外してしまったのだと思いましたので、
    こちらで、再度回答マークを付けさせてもらいました。

    和人さんのアドバイスを受けて、再度見直した所、問題を解決することができたとのことなので、問題ないとは思いますが、
    不適切と思いましたら、_kiyoさんの方で、回答マークを削除することも可能です。

    今後ともMSDNフォーラムをよろしくお願いします。


    マイクロソフト株式会社 フォーラム オペレーター 高橋春樹
    2009年8月31日 6:14
  • 高橋春樹さん

    初めまして。

    和人さんの回答マークが外れてしまっていることに気づいておりませんでした。
    ですので、つけていただいたままでOKです。
    どこまでも確認不足ですね・・・以後気をつけます。

    サポートして頂きありがとうございます。
    今後ともよろしくお願い致します。

    2009年8月31日 8:14