#150 – An Example of Using PropertyChanged and CoerceValue Callbacks

The PropertyChangedCallback and CoerceValueCallback can be used to enforce relationships between properties on an object.  Here’s an example, showing the relationship between BirthYear, MarriageYear and DeathYear properties on a Person object.

The BirthYear property:

        public int BirthYear
        {
            get { return (int)GetValue(BirthYearProperty); }
            set { SetValue(BirthYearProperty, value); }
        }

        public static readonly DependencyProperty BirthYearProperty =
            DependencyProperty.Register("BirthYear", typeof(int), typeof(Person),
                new PropertyMetadata(
                    1900,       // Default
                    new PropertyChangedCallback(OnBirthYearChanged)));

        public static void OnBirthYearChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Person p = (Person)d;
            p.CoerceValue(DeathYearProperty);
            p.CoerceValue(MarriageYearProperty);
        }

The DeathYear property:

        public int DeathYear
        {
            get { return (int)GetValue(DeathYearProperty); }
            set { SetValue(DeathYearProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DeathYear.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DeathYearProperty =
            DependencyProperty.Register("DeathYear", typeof(int), typeof(Person),
                new PropertyMetadata(
                    1900,       // Default
                    new PropertyChangedCallback(OnDeathYearChanged),
                    new CoerceValueCallback(CoerceDeathYear)));

        public static void OnDeathYearChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Person p = (Person)d;
            p.CoerceValue(MarriageYearProperty);
        }

        public static object CoerceDeathYear(DependencyObject d, object value)
        {
            Person p = (Person)d;
            int deathYear = (int)value;

            if (deathYear < p.BirthYear)
                deathYear = p.BirthYear;

            return deathYear;
        }

The MarriageYear property:

        public int MarriageYear
        {
            get { return (int)GetValue(MarriageYearProperty); }
            set { SetValue(MarriageYearProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DeathYear.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MarriageYearProperty =
            DependencyProperty.Register("MarriageYear", typeof(int), typeof(Person),
                new PropertyMetadata(
                    1900,       // Default
                    null,
                    new CoerceValueCallback(CoerceMarriageYear)));

        public static object CoerceMarriageYear(DependencyObject d, object value)
        {
            Person p = (Person)d;
            int marriageYear = (int)value;

            if (marriageYear < p.BirthYear)
                marriageYear = p.BirthYear;
            if (marriageYear > p.DeathYear)
                marriageYear = p.DeathYear;

            return marriageYear;
        }
Advertisement