using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace ConsoleApplication1
{
    /// <summary>
    /// DependencyProperty本身并不提供取值、赋值操作,而是由DependencyObject来负责
    /// </summary>
    public class DPCustomPeople : DependencyObject
    {



        public string Name
        {
            get { return (string)GetValue(NameProperty); }
            set { SetValue(NameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NameProperty.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty NameProperty =
        //    DependencyProperty.Register("Name", typeof(string), typeof(DPCustomPeople), new PropertyMetadata(string.Empty));

        public static readonly DependencyProperty NameProperty =
            DependencyProperty.Register("Name", typeof(string), typeof(DPCustomPeople), new UIPropertyMetadata(string.Empty));

        public static readonly DependencyProperty AgeProperty =
        DependencyProperty.Register("Age", typeof(int), typeof(DPCustomPeople));

        public int Age
        {
            get { return (int)GetValue(AgeProperty); }
            set { SetValue(AgeProperty, value); }
        }

        public void DisplayAgeProperty()
        {
            Console.WriteLine("DPName:" + DPCustomPeople.AgeProperty.Name);
            Console.WriteLine("DPPropertyType:" + DPCustomPeople.AgeProperty.PropertyType);
            Console.WriteLine("DPOwnerType:" + DPCustomPeople.AgeProperty.OwnerType);
        }

        public void DPPropertyBasicOperator()
        {
            Console.WriteLine("Age: " + this.GetValue(DPCustomPeople.AgeProperty));
            this.SetValue(DPCustomPeople.AgeProperty, 23);
            Console.WriteLine("ChangedAge: " + this.GetValue(DPCustomPeople.AgeProperty));
        }

        public void DPPropertyBasicOperatorUsingProperty()
        {
            Console.WriteLine("Age: " + this.Age);
            this.SetValue(DPCustomPeople.AgeProperty, 23);
            Console.WriteLine("ChangedAge: " + this.Age);
        }

        public void DPPropertyClearOperator()
        {
            Console.WriteLine("Name: " + this.Name);
            this.Name = "Chang weihua";
            Console.WriteLine("ChangedName: " + this.Name);
            this.ClearValue(NameProperty);
            Console.WriteLine("Name: " + this.Name);
        }

    }

    /// <summary>
    /// 默认赋值一般在构造函数中进行,但这却不是默认值(在依赖属性出现之前这的确是),特别是在派生类重写属性的时候
    /// </summary>
    public class Student : DPCustomPeople
    {
        public Student()
        {
            this.Name = "Chang VH";
        }

        public void TestSubDefaultDPValue()
        {
            Console.WriteLine("Clear Before: " + this.Name);
            this.ClearValue(Student.NameProperty);
            Console.WriteLine("Clear After: " + this.Name);
        }


        #region 属性变更通知



        public bool IsBoy
        {
            get { return (bool)GetValue(IsBoyProperty); }
            set { SetValue(IsBoyProperty, value); }
        }

        //public static readonly DependencyProperty IsBoyProperty =
        //    DependencyProperty.Register("IsBoy", typeof(bool), typeof(Student), new UIPropertyMetadata(false, (d, e) => { }));

        public static readonly DependencyProperty IsBoyProperty =
            DependencyProperty.Register("IsBoy", typeof(bool), typeof(Student), new UIPropertyMetadata(false, new PropertyChangedCallback(IsBoyPropertyChangedCallback)));


        public static void IsBoyPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Student student = d as Student;
            if (student.IsBoy)
            {
                Console.WriteLine("Hello, Boy !");
            }
            else
            {
                Console.WriteLine("Hello, Girl !");
            }
        }

        public void TestPropertyChangedCallback()
        {
            RaiseIsBoyPropertyChangedCallback();
            this.IsBoy = false;
            this.IsBoy = true;
            this.IsBoy = true;
        }

        //1、 依赖属性的默认值是不会触发属性变更通知的
        //2、 手动触发属性变更通知
        //3、 当有属性变更通知时,一定要保证属性默认值类型的正确性

        private void RaiseIsBoyPropertyChangedCallback()
        {
            IsBoyPropertyChangedCallback(this, new DependencyPropertyChangedEventArgs(Student.IsBoyProperty, Student.IsBoyProperty.DefaultMetadata.DefaultValue, true));
        }

        #endregion

        #region 强制属性回调,不管属性值有无发生变化,都会进入回调方法

        public int Score
        {
            get { return (int)GetValue(ScoreProperty); }
            set { SetValue(ScoreProperty, value); }
        }

        public static readonly DependencyProperty ScoreProperty =
            DependencyProperty.Register("Score", typeof(int), typeof(Student), new UIPropertyMetadata(0, null, new CoerceValueCallback(ScoreCoerceValueCallback)));

        public static object ScoreCoerceValueCallback(DependencyObject d, object baseValue)
        {
            Console.WriteLine(baseValue);
            return baseValue;
        }

        public void TestScoreCoerceValueCallback()
        {
            this.Score = 0;
            this.Score = 0;
            this.Score = 0;
        }

        #endregion

    }

}
站内公告