Child object property change fires parents DependencyPropertyChanged callback?

安稳与你 提交于 2019-12-23 06:06:03

问题


In defining a base class inheriting an the Animatable, class, I have discovered what I am finding to be some odd behavior.

When I create a Child DependencyProperty within a 'Parent' class, then define an instance of that 'Parent' class, then alter a property on the parents child, the PropertyChangedCallback I defined for the Parents Child property fires.

In compliance with the requisite Minimal, Complete and Verifiable Example:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Animation;

namespace MCVE {
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class Program {
        [STAThread]
        public static int Main( ) {
            Parent p = new Parent( );
            p.Child.Trigger = new object( );
            return 0;
        }
    }

    public abstract class Base : Animatable {
        public static readonly DependencyProperty TriggerProperty;
        static Base( ) =>
            TriggerProperty = DependencyProperty.Register(
                "Trigger", typeof( object ), typeof( Base) );
        public object Trigger {
            get => this.GetValue( TriggerProperty );
            set => this.SetValue( TriggerProperty, value );
        }
    }
    public class Parent : Base {
        public static readonly DependencyProperty ChildProperty;

        static Parent( ) {
            ChildProperty = DependencyProperty.Register(
                "Child", typeof( Child ), typeof( Parent ),
                new PropertyMetadata(  null as Child, _OnChildChanged ) );

            void _OnChildChanged(
                DependencyObject sender,
                DependencyPropertyChangedEventArgs e ) =>
                Console.WriteLine( "Child Changed!" );
        }

        public Parent( ) : base( ) =>
            this.Child = new Child( );


        public Child Child {
            get => this.GetValue( ChildProperty ) as Child;
            set => this.SetValue( ChildProperty, value );
        }

        protected override Freezable CreateInstanceCore( ) => new Parent( );
    }
    public class Child : Base {
        public Child( ) : base( ) { }
        protected override Freezable CreateInstanceCore( ) => new Child( );
    }
}

To reproduce:

  1. Create WPF Project. Target .Net 4.7.2.
  2. Select App.xaml
  3. Under Properties, change Build Action to Page
  4. Paste code into App.xaml.cs. Overwrite EVERYTHING.

Running this code, you should see the message print twice within the console.

Why is this happening? Is there a way to STOP it from happening?

Follow Up Here:


回答1:


The message print 2 times in console because Child property was set 2 times:

  • 1st time in Parent constructor( this.Child = new Child( );)
  • 2nd time when you call p.Child.Trigger = new object( );

I think in your case, you can compare new value and old value of Child property in _OnChildChanged() to prevent the problem:

            void _OnChildChanged(
                DependencyObject sender,
                DependencyPropertyChangedEventArgs e)
            {
                if (e.NewValue != e.OldValue)
                {
                    Console.WriteLine("Child Changed!");
                }
            }

Regards!



来源:https://stackoverflow.com/questions/53918882/child-object-property-change-fires-parents-dependencypropertychanged-callback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!