【发布时间】:2019-05-23 22:31:46
【问题描述】:
在定义继承 Animatable 类的基类时,我发现了一些奇怪的行为。
当我在“父”类中创建子 DependencyProperty,然后定义该“父”类的实例,然后更改父子的属性时,我为父子属性定义的 PropertyChangedCallback 将触发。
符合必要的Minimal, Complete and Verifiable Example:
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。覆盖所有内容。
运行此代码,您应该会在控制台中看到消息打印两次。
为什么会这样?有没有办法阻止它发生?
跟进Here:
【问题讨论】:
-
嗨,我试图运行你的代码,它抛出 System.TypeInitializationException 异常作为这行代码:“ChildProperty = DependencyProperty.Register("Child", typeof(Child), typeof(Parent) , new PropertyMetadata(null as Child, _OnChildChanged));"
-
@NhanPhan 您将项目创建为控制台应用程序还是 WPF 应用程序。它需要是一个 WPF 应用程序。
-
请注意,写
null as Child是多余的,原因有两个。首先,null可以分配给每个引用类型,其次,PropertyMetadata 构造函数的默认值参数的类型是object。 -
@Clemens 这很公平。这只是我自己的个人喜好,因为我有一些用于注册依赖属性的实用方法,一个期望
default值,一个期望PropertyMetaData,所以如果我没有通过 @ 明确提供属性类型,它往往会感到不安987654335@.
标签: c# wpf xaml dependency-properties dependencyobject