none
自作プロパティのアニメーション RRS feed

  • 質問

  • お世話になります。

    自作クラスの自作プロパティをアニメーション化しようとしています。

    【概要】
    ・自作クラスは、ボタンのようなイメージです。
    ・アニメーションで、この自作クラスの幅を変えようとしております。


    DependencyPropertyの登録まではいったのですが、いざ使ってみるとアニメーションが反映されません。エラーなどは表示されておりません。

    アドバイス宜しくお願いいたします。

        //自作クラス
    
        public class myButton : DependencyObject
    
        {
    
            public Button btn;
    
    
    
            public myButton()
    
            {
    
                btn = new Button();
    
                
    
            }
    
    
    
            public static readonly DependencyProperty myWidthProperty =
    
                DependencyProperty.Register("myWidth", typeof(double), typeof(myButton));
    
    
    
            public double myWidth
    
            {
    
                //get { return (double)GetValue(myWidthProperty); }
    
                //set { SetValue(myWidthProperty, value); }
    
    
    
                get { return (double)btn.Width; }
    
                set { btn.Width = (double)value; }
    
    
    
            }
    
    
    
    
    
            public static readonly DependencyProperty myHeightProperty =
    
               DependencyProperty.Register("myHeight", typeof(double), typeof(myButton));
    
    
    
            public double myHeight
    
            {
    
                get { return (double)btn.Height; }
    
                set { btn.Height = (double)value; }
    
    
    
            }
    
    
    
    	public void BeginStoryboard(Storyboard sb){
    
                btn.BeginStoryboard(sb);
    
            }
    
        }
    
    

    //自作クラスを呼び出してアニメーションを実行する側側
    
                myButton b = new myButton();
    
                b.myWidth = 99;
    
                
    
                
    
                Storyboard storyboard = new Storyboard();
    
                DoubleAnimation animationWidth = new DoubleAnimation();
    
    
    
                animationWidth.From = 10;
    
                animationWidth.To = 20;
    
                animationWidth.Duration = TimeSpan.FromMilliseconds(700);
    
    
    
    
    
                Storyboard.SetTargetProperty(animationWidth, new PropertyPath(myButton.myWidthProperty));
    
                storyboard.Children.Add(animationWidth);
    
    
    
    
    
                b.BeginStoryboard(storyboard);
    
    
    
                //デバッグすると、値が20になってない。 99のまま。
    
                MessageBox.Show("myWidthプロパティ:" + b.myWidth);
    
    
    2010年2月18日 5:52

回答

  • 自己レスです。


    すいません。解決しました。

    コーディングミスでした。。。

    呼び出し元
    Storyboard.SetTarget(anim, this);

    Storyboard.SetTarget(anim, hoge);

    有難う御座いました。

    • 回答としてマーク sumi_sumi 2010年2月23日 6:48
    2010年2月23日 6:48

すべての返信

  • アニメーションを含むほとんどの場合、依存関係プロパティの CLR ラッパプロパティ(HogeProperty に対する Hoge)は呼び出されません。直接 HogeProperty を使って SetValue されます。
    他のプロパティに影響させる場合、FrameworkPropertyMetadata のコンストラクタに渡す PropertyChangedCallback 内で処理を行うなどします。

    が、それ以前に、この myButton をどう使うのか存じませんがそれは間違った手法である可能性が高そうです。
    こういうクラスを作る必然性が考えられません。
    2010年2月18日 9:26
  • Hogliang 様

    アドバイス有難う御座います。

    ちょうど今、ネット上にあったコードを参考にしながらPropertyChangedCallbackを実装してました。
    まだ完成してませんがこの中でセットすれば良いのかなと予想してます。


    >こういうクラスを作る必然性が考えられません。
    あ。これは、あくまで勉強用といいますか、テスト用なんです。
    すいません。ご指摘有難う御座います。

    2010年2月18日 10:00
  • 以下のサイトを参考にしながら自作プロパティのアニメーションは出来ました。
    ですが、こちらは自分のクラスの中でアニメーションを実行しています。
    http://forums.silverlight.net/forums/p/18949/64470.aspx


    実現したいのは、他のクラスからアニメーションを実行することです。


    自作プロパティがあるクラスをHoge、
    アニメーションを開始する(呼び出し元の)クラスをWindow1として分けて作成してみました。


    単純にWindow1からHogeをnewし、BeginStoryboardでいけるかと思いましたがダメでした。


    まず、PropertyPathの設定を以下のようにした場合
    Storyboard.SetTargetProperty(anim, new PropertyPath("MyPoint"));
    「プロパティ パス 'MyPoint' に解決できないプロパティ参照があります。」という実行時エラーになります。


    次のようにした場合
    Storyboard.SetTargetProperty(anim, new PropertyPath(Hoge.MyPointProperty));
    エラーなく実行出来るのですが、HogeのPropertyChangedCallbackが呼ばれません。
    よってアニメーションが実行されません。


    どこをどう修正すれば良いかまったく分かりません。。。


    どうかアドバイスいただければ幸いです。


    Window1

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Media.Animation;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// Window1.xaml の相互作用ロジック
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                Hoge hoge = new Hoge();
    
                PointAnimation anim = new PointAnimation();
                anim.To = new Point(10, 10);
                anim.Duration = new Duration(TimeSpan.FromSeconds(1.0));
    
                Storyboard _story = new Storyboard();
    
                //Storyboard.SetTargetProperty(anim, new PropertyPath("MyPoint"));
                //Storyboard.SetTargetProperty(anim, new PropertyPath("Hoge.MyPoint"));
                Storyboard.SetTargetProperty(anim, new PropertyPath(Hoge.MyPointProperty));
    
                _story.Children.Add(anim);
                Storyboard.SetTarget(anim, this);
    
                
                hoge.BeginStoryboard(_story);
                
    
            }
        }
    }
    

    Hoge(UserControl)
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Media.Animation;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// UserControl1.xaml の相互作用ロジック
        /// </summary>
        public partial class Hoge : UserControl
        {
            public Hoge()
            {
                InitializeComponent();
            }
    
    
    
            #region MyPoint
            public static readonly DependencyProperty MyPointProperty =
            DependencyProperty.Register("MyPoint", typeof(Point), typeof(Hoge),
            new PropertyMetadata(
            new PropertyChangedCallback(OnMyPointChanged)));
    
            public Point MyPoint
            {
                get { return (Point)GetValue(MyPointProperty); }
                set { SetValue(MyPointProperty, value); }
            }
            private static void OnMyPointChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ((Hoge)d).OnMyPointChanged(e);
            }
    
            protected virtual void OnMyPointChanged(DependencyPropertyChangedEventArgs e)
            {
                Point value = (Point)e.NewValue;
                System.Diagnostics.Debug.WriteLine("value = " + value.ToString());
               
            }
            #endregion
    
           
    
        }
    }
    

    window1のxaml
    <Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <Button Margin="73,114,58,36" Name="button1" Click="button1_Click">Button</Button>
        </Grid>
    </Window>
    
    2010年2月23日 6:25
  • 自己レスです。


    すいません。解決しました。

    コーディングミスでした。。。

    呼び出し元
    Storyboard.SetTarget(anim, this);

    Storyboard.SetTarget(anim, hoge);

    有難う御座いました。

    • 回答としてマーク sumi_sumi 2010年2月23日 6:48
    2010年2月23日 6:48