子对象属性更改触发父母DependencyPropertyChanged回调? [英] Child object property change fires parents DependencyPropertyChanged callback?

查看:198
本文介绍了子对象属性更改触发父母DependencyPropertyChanged回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在定义继承 Animatable 类的基类时,我发现自己发现了一些奇怪的行为。

In defining a base class inheriting an the Animatable, class, I have discovered what I am finding to be some odd behavior.

当我在父级类中创建子级DependencyProperty时,然后定义该父级类的实例,然后更改父级子级上的属性,将触发为父级子级属性定义的PropertyChangedCallback。

When I create a Child DependencyProperty within a 'Parent' class, then define an instance of that 'Parent' class, then alter a property on the parents child, the PropertyChangedCallback I defined for the Parents Child property fires.

符合必需的最小,完整和可验证的示例:

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项目。目标.Net 4.7.2。

  2. 选择 App.xaml

  3. <$ c以下$ c>属性,将构建操作更改为页面

  4. 将代码粘贴到 App.xaml.cs 中。覆盖所有内容。

  1. Create WPF Project. Target .Net 4.7.2.
  2. Select App.xaml
  3. Under Properties, change Build Action to Page
  4. Paste code into App.xaml.cs. Overwrite EVERYTHING.

运行此代码,您应该在控制台中看到两次打印消息。

Running this code, you should see the message print twice within the console.

为什么会这样?有没有办法阻止它发生?

Why is this happening? Is there a way to STOP it from happening?

跟进此处

推荐答案

该消息在控制台中打印2次,因为子属性设置了2次:

The message print 2 times in console because Child property was set 2 times:


  • 第一次在父级构造函数中使用(this.Child = new Child();)

  • 第二次调用p.Child.Trigger = new object();

我认为在您的情况下,您可以在_OnChildChanged()中比较子属性的新值和旧值,以防止出现此问题:

I think in your case, you can compare new value and old value of Child property in _OnChildChanged() to prevent the problem:

            void _OnChildChanged(
                DependencyObject sender,
                DependencyPropertyChangedEventArgs e)
            {
                if (e.NewValue != e.OldValue)
                {
                    Console.WriteLine("Child Changed!");
                }
            }

致谢!

这篇关于子对象属性更改触发父母DependencyPropertyChanged回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆