关注this个问题。
显然,出于某种原因,当我设置Parent.Child
对象的Child.Trigger
属性时,在显式设置Parent.Child
属性(在构造函数内部或在构造函数外部)后, ,Parent.Child
对象又被设置了。这可以通过中断静态构造函数中定义的_OnChildChanged
方法来观察。在调用它的第二个实例上,您可以看到e.OldValue
不为空,并且它与e.NewValue
相同。
为什么设置Child
属性时又要设置Parent
的{{1}}属性?
符合必要的最低Complete and Verifiable Example:
Trigger
要复制:
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( );
}
}
App.xaml
下,将Properties
更改为Build Action
Page
中。覆盖所有内容。答案 0 :(得分:1)
我看了 Animatable 类的实现。它是从 freezable 类继承的,而该类又是 DependencyObject 类的继承。
在 freezable 内部,它重写了 DependencyObject 中的 OnPropertyChanged 事件,并调用所有对Freezable类型的依赖项属性做出响应的处理程序。
这意味着当Child类中的任何依赖项值发生更改时,将调用Freezable类中的 OnPropertyChanged 事件。而且 FireChanged()也已调用。在 FireChange()方法内部,它将调用 GetChangeHandlersAndInvalidateSubProperties 来检查子类中的所有更改,然后只要有任何依赖项,就会调用 _OnChildChanged 属性已更改。
您可以引用Freezable类here的源代码
Freezable Objects Overview的Creating Your Own Freezable Class 部分(重点是我的)中也记录了这种行为:
从Freezable派生的类具有以下功能。
特殊状态:只读(冻结)和可写状态。
线程安全:冻结的Freezable可以在线程之间共享。
详细的更改通知:与其他DependencyObjects不同,Freezable对象在子属性值更改时提供更改通知。
轻松克隆:Freezable类已经实现了几种产生深克隆的方法。