Изменение свойства дочернего объекта вызывает родительский обратный вызов DependencyPropertyChanged? - PullRequest
0 голосов
/ 25 декабря 2018

Определяя базовый класс, унаследованный от класса Animatable, я обнаружил, что я считаю странным поведение.

Когда я создаю Child DependencyProperty в классе 'Parent', тогдаопределить экземпляр этого класса 'Parent', затем изменить свойство родительского дочернего элемента, PropertyChangedCallback, который я определил для свойства Parents Child, запускается.

В соответствии с обязательным Минимальным, полным и проверяемым примером:

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( );
    }
}

Воспроизвести:

  1. Создать проект WPF.Target .Net 4.7.2.
  2. Выберите App.xaml
  3. Под Properties, измените Build Action на Page
  4. Вставьте код в App.xaml.cs.Перезаписать ВСЕ.

Запустив этот код, вы должны увидеть сообщение, дважды напечатанное на консоли.

Почему это происходит?Есть ли способ, чтобы остановить это?

Follow Up Здесь :

1 Ответ

0 голосов
/ 25 декабря 2018

Сообщение печатается 2 раза в консоли, поскольку свойство Child было установлено 2 раза:

  • 1-й раз в конструкторе Parent (this.Child = new Child ();)
  • 2ndвремя, когда вы вызываете p.Child.Trigger = new object ();

Я думаю, в вашем случае вы можете сравнить новое значение и старое значение свойства Child в _OnChildChanged () для предотвращения проблемы:

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

С уважением!

...