WPF/Silverlight学习 - Dependency Property

  这两天看到Dependency Property,这东西比以前Winform中的Property(CLR Property, 看到别人这么叫)强大多了。以前项目中为了设置字体,缓 存了所有的空间并挨个设置,现在有了Dependency Property,只要设置窗体的字体,所有子控件都会继承窗体的设置。 在layout的配合下,还可以方便实现窗体及控件自适应字体的大小。

  首先是一个WPF的例子,改造自《WPF程序设计指南》第8章。我改的好无聊 -_-

Button控件,改变Text属性时会自动在后面加上“_Eric”
    public class EricButton : Button
    {
        public static readonly DependencyProperty TextProperty;
        public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }

        static EricButton()
        {
            FrameworkPropertyMetadata meta = new FrameworkPropertyMetadata();
            meta.DefaultValue = "";
            meta.AffectsMeasure = true;
            meta.Inherits = true;
            meta.PropertyChangedCallback += OnTextChanged;
            TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(EricButton), meta);
        }
        static void OnTextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            EricButton btn = obj as EricButton;
            btn.Content = btn.Text + "_Eric";
        }
    }
自定义窗体,同样定义了 TextProperty
调用
    class Program : WpfConsole.DP.EricWindow
    {
        [STAThread]
        static void Main(string[] args)
        {
            Application app = new Application();
            app.Run(new Program());
        }

        public Program()
        {
            SizeToContent = System.Windows.SizeToContent.WidthAndHeight;
            ResizeMode = System.Windows.ResizeMode.CanMinimize;
            StackPanel stack = new StackPanel();
            Content = stack;

            DP.EricButton eb1 = new DP.EricButton();
            eb1.Content = "button 1";
            eb1.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            eb1.Click += new RoutedEventHandler(eb1_Click);

            DP.EricButton eb2 = new DP.EricButton();
            eb2.Content = "button 2";
            eb2.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            eb2.Click += new RoutedEventHandler(eb2_Click);

            stack.Children.Add(eb1);
            stack.Children.Add(eb2);

        }

        void eb1_Click(object sender, RoutedEventArgs e)
        {
            Text = "btn 1 clicked " + DateTime.Now.Second;
        }

        void eb2_Click(object sender, RoutedEventArgs e)
        {
            (sender as DP.EricButton).Text = "btn 2 clicked " + DateTime.Now.Second;
        }
    }

  执行代码,点击btn1时,设置了Window的Text,两个button的content也跟着改变。点击btn2,设置btn2的text,此时再点击btn1,btn2本身的text属性已赋值,优先级高于从window继承,text不再跟着window改变。

  我乱试了一下,如果在自定义窗体中,TextProperty用下面的方式定义

 TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(EricWindow));

窗体的Text改变后,button是不会跟着变的。也就是说Button和Window的TextProperty必须有Owner的关系在,才会从Window继承TextProperty的值。

 

  至于Silverlight,它本身是WPF的一个子集。具体用法基本上一样,但是功能上没有WPF丰富。经过多番查找,Silverlight里控件是不能继承父控件的属性的。DependencyProperty没有AddOwner方法。

  以后有新发现再补充。

        

 

 

 

posted on 2012-08-14 13:06  YanYangjiang  阅读(263)  评论(0编辑  收藏  举报

导航