c#数据绑定最小测试用例中的错误更新通知

本文关键字:错误 更新 通知 测试用例 数据绑定 | 更新日期: 2023-09-27 18:15:48

我用c#创建了一个最小的测试场景来探索数据绑定的机制。背景是:我想表明,更改绑定在数据绑定中的属性的子属性不会触发对绑定的另一端的更新(只有更改绑定属性本身应该触发更新)!

但是我发现它确实在我的测试用例中,我很困惑我是否在我的测试用例中有一个错误或数据绑定实际上是这样工作的。这个测试用例非常方便:

namespace DatabindingMinimal
{
    // Person with a name
    public class Person
    {
        public String Name { get; set; }
        public Person(String name)
        {
            this.Name = name;
        }
    }
    // class exposing a Person as best Friend
    // INotifyPropertyChanged is not implemented here
    public class Friends 
    {
        public Person BestFriend { get; set; }
        public Friends(String bestFriendName)
        {
            this.BestFriend = new Person(bestFriendName);
        }
    }
    // class exposing a Person as father as DependencyProperty
    public class Parents : DependencyObject
    {
        public static DependencyProperty FatherProperty =
            DependencyProperty.Register("Father", typeof(Person), typeof(Parents));
        public Person Father
        {
            get { return (Person)this.GetValue(FatherProperty); }
            set { this.SetValue(FatherProperty, value); }
        }
        public Parents(String fatherName)
        {
            this.Father = new Person(fatherName);
        }
    }
    // test the databinding between Friends and Parents
    class Program
    {
        static void Main(string[] args)
        {
            Friends f = new Friends("Humphrey");
            Parents p = new Parents("Rudolph");
            Binding bindBeziehungen = new Binding("BestFriend");
            bindBeziehungen.Source = f;
            bindBeziehungen.Mode = BindingMode.TwoWay;
            BindingOperations.SetBinding(p, Parents.FatherProperty, bindBeziehungen);
            f.BestFriend.Name = String.Empty;   // the p.Father.Name is now set Empty as well
            System.Console.WriteLine(f.BestFriend.Name);
            System.Console.WriteLine(p.Father.Name);
            // ... Both Strings are empty in output now!
            if (Object.ReferenceEquals(f.BestFriend, p.Father))
                System.Console.WriteLine("identical");    // this is true here!
        }
    }
}

测试用例将朋友类作为源绑定到父类的实例作为目标。friends类没有任何通知机制!但是改变f.BestFriend.Name属性会改变p.Father.Name属性!更改绑定的BestFriend属性本身不会更新任何内容(如预期的那样):

f.BestFriend = new Person("");    // p.Father does not change here!

当直接更改f.BestFriend时,最后的引用也不相等!

问题:那么,在创建绑定并在一侧进行更新后,绑定属性的引用是相等的,这正常吗?

为什么改变f.BestFriend.Name会触发一个更新,即使没有INotifyPropertyChanged实现?

我有一种感觉,绑定分配一个绑定的Person属性的引用来匹配另一个在幕后?!有人能解决这个问题吗?

c#数据绑定最小测试用例中的错误更新通知

我猜你所问的问题不是一个问题,而是一些混淆或误解的结果。

看看你的数据绑定。这个绑定所做的最重要的事情是设置p。父f.BestFriend的值相同。可以把它看作相当于下面的代码:

p.Father = f.BestFriend;

(好吧,就绑定和DependencyProperty的维护方式而言,绑定与这段代码并不完全等同。但在这个问题的上下文中,这是一个足够好的简化。

结果是什么?绑定初始化后,p。父f。BestFriend将引用相同的 Person对象。

实际上,你可以用上面的代码行替换代码中的绑定,并体验到完全相同的效果。

如果您将Name属性设置为另一个值,则没有魔术更新(或魔术更新通知),例如:
f.BestFriend.Name = String.Empty; 

当然你会看到f.BestFriend的值是一样的。Name和for p.Father。名称,因为f。好朋友指向非常相同的单个Person对象——顺便说一下,您已经在代码中的最后一个if语句中发现了这一点。

没有神奇的从一个Person对象到另一个Person对象的属性更新,因为,再一次,您的代码只处理一个Person对象(而不是两个,您似乎认为)。

关于

f.BestFriend = new Person("");    // p.Father does not change here!

当然是p。父亲没有改变,你已经知道为什么了。尽管 f。好友是绑定源,绑定时不会知道是否/何时的值为f。BestFriend(该值是对Person对象的引用)更改,因为由于缺乏INotifyPropertyChanged实现,它没有被通知。因为绑定没有被通知,所以它不会更新p.Father的值。在执行这行代码之后,f。BestFriend将指向与p. father 不同的 Person对象。

从本质上讲,所有你想知道的和你问的都是来自一个误解。没有两个Person对象,没有绑定进行更新(除了作为其初始设置的一部分),并且根本没有发生属性更改通知…