为什么要再次设置此Animatable属性



跟进此问题。

显然,由于某种原因,在显式设置了Parent.Child属性(在构造函数内部或显式设置在构造函数外部)之后,当我设置Parent.Child对象的Child.Trigger属性时,Parent.Child对象再次被设置。这可以通过破坏静态构造函数中定义的_OnChildChanged方法来观察。在被调用的第二个实例中,您可以看到e.OldValue不是null,并且它与e.NewValue相同。

为什么在设置Trigger属性时再次设置ParentChild属性?

符合必要的最小、完整和可验证示例:

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中。覆盖所有内容

我研究了Animatable类的实现。它继承自freezable类,后者继承自DependencyObject类别。

freezable内部,它覆盖DependencyObject中的OnPropertyChanged事件,并调用所有处理程序,这些处理程序是对freezable类型的更改依赖属性的响应。

这意味着当Child类中的任何依赖项值发生更改时,将调用Freezable类中的OnPropertyChanged事件。FireChanged()也调用了。在FireChange()方法中,它将调用GetChangeHandlersAndInvalidateSubProperties来检查从子类更改的所有内容,然后每当其任何依赖属性发生更改时,都将调用
_OnChildChanged。

你可以在这里引用Freezable类的源代码


此行为也记录在"可冻结对象概述"的"创建自己的可冻结类"一节中(强调矿):

从Freezable派生的类具有以下功能。

  • 特殊状态:只读(冻结)和可写状态。

  • 线程安全:冻结的Freezable可以在线程之间共享。

  • 详细的更改通知:与其他DependencyObjects不同,Freezable对象在子属性值更改时提供更改通知

  • 易于克隆:Freezable类已经实现了几种生成深度克隆的方法。

相关内容

  • 没有找到相关文章

最新更新