Изменение свойства дочернего объекта вызывает родительский обратный вызов DependencyPropertyChanged?
При определении базового класса, наследующего 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( );
}
}
Воспроизвести:
- Создать проект WPF. Target .Net 4.7.2.
- Выбрать
App.xaml
- Под
Properties
, менятьBuild Action
вPage
- Вставьте код в
App.xaml.cs
, Перезаписать ВСЕ.
Запустив этот код, вы должны увидеть сообщение, напечатанное дважды в консоли.
Почему это происходит? Есть ли способ, чтобы остановить это?
Следуйте здесь:
1 ответ
Сообщение печатается 2 раза в консоли, потому что свойство Child было установлено 2 раза:
- 1-й раз в конструкторе Parent (this.Child = new Child ();)
- 2-й раз при вызове p.Child.Trigger = new object();
Я думаю, что в вашем случае вы можете сравнить новое значение и старое значение свойства Child в _OnChildChanged(), чтобы предотвратить проблему:
void _OnChildChanged(
DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != e.OldValue)
{
Console.WriteLine("Child Changed!");
}
}
С уважением!