c# - 子对象属性更改触发父母 DependencyPropertyChanged 回调?
问题描述
在定义继承Animatable
, 类的基类时,我发现了一些奇怪的行为。
当我在“父”类中创建子 DependencyProperty,然后定义该“父”类的实例,然后更改父子的属性时,我为父子属性定义的 PropertyChangedCallback 会触发。
符合必要的最小、完整和可验证示例:
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 项目。目标.Net 4.7.2。
- 选择
App.xaml
- 在 下
Properties
,更改Build Action
为Page
- 将代码粘贴到
App.xaml.cs
. 覆盖一切。
运行此代码,您应该会在控制台中看到消息打印两次。
为什么会这样?有没有办法阻止它发生?
在这里跟进:
解决方案
消息在控制台中打印 2 次,因为 Child 属性设置了 2 次:
- 第一次在父构造函数中(this.Child = new Child();)
- 第二次调用 p.Child.Trigger = new object();
我认为在您的情况下,您可以比较_OnChildChanged()中 Child 属性的新值和旧值以防止出现问题:
void _OnChildChanged(
DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != e.OldValue)
{
Console.WriteLine("Child Changed!");
}
}
问候!
推荐阅读
- php - 有人能告诉我 DateTimeZone::getOffset PHP 函数是如何工作的吗?
- apache-kafka - 我们可以更新 kafka 0.10 中的消费者偏移量吗?
- robotframework - RobotFramework/RIDE 无法通过示例测试 - “未找到名称为 'Run ${sakura}' 的关键字。”
- azure - 如何使用逻辑应用程序将数组值插入表中
- docker - 使用 Google Cloud Build,我如何运行执行 docker 和 kubectl 命令的 Makefile?
- sql - 如何正确地将这个复杂的 JSON 转换为 SQL 表?
- angular - 我们可以创建 react-native + Angular 应用程序吗?是的,那怎么办?
- c# - 如何从 C# 中的匿名 select 语句返回多个值
- javascript - 我们可以在 firebase 的云功能中使用 async/await 吗?
- .net - Visual Studio 自定义构建配置工作机制行为 Debug/Release 还是别的什么?