【问题标题】:Understanding how PropertyChanged mechanism works (workflow)了解 PropertyChanged 机制的工作原理(工作流程)
【发布时间】:2015-01-20 10:36:52
【问题描述】:

说明: 1.- 我不知道这是否有一个特定的名称或单词可以用英语或编程俚语来引用它,所以这可能是一个重复的帖子,因为我无法查看它。

2.- 我完全是新手,我从未使用过处理程序,所以这是问题的一部分。

我正在尝试了解 NotifyPropertyChanged 机制的工作原理。基于:INotifyPropertyChanged,重点举例。 (我看的是西班牙文,上面如果不自动改的话可以改成英文原版。

现在我要提取让我想知道的主要代码,并尝试分析它。希望你能告诉我哪里(如果存在)我错了,我不能理解。 让我们关注实现接口的类

// This is a simple customer class that 
// implements the IPropertyChange interface.
public class DemoCustomer : INotifyPropertyChanged
{
    // These fields hold the values for the public properties.
    private Guid idValue = Guid.NewGuid();
    private string customerNameValue = String.Empty;
    private string phoneNumberValue = String.Empty;

    public event PropertyChangedEventHandler PropertyChanged;

    // This method is called by the Set accessor of each property.
    // The CallerMemberName attribute that is applied to the optional propertyName
    // parameter causes the property name of the caller to be substituted as an argument.
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    // The constructor is private to enforce the factory pattern.
    private DemoCustomer()
    {
        customerNameValue = "Customer";
        phoneNumberValue = "(312)555-0100";
    }

    // This is the public factory method.
    public static DemoCustomer CreateNewCustomer()
    {
        return new DemoCustomer();
    }

    // This property represents an ID, suitable
    // for use as a primary key in a database.
    public Guid ID
    {
        get
        {
            return this.idValue;
        }
    }

    public string CustomerName
    {
        get
        {
            return this.customerNameValue;
        }

        set
        {
            if (value != this.customerNameValue)
            {
                this.customerNameValue = value;
                NotifyPropertyChanged();
            }
        }
    }

    public string PhoneNumber
    {
        get
        {
            return this.phoneNumberValue;
        }

        set
        {
            if (value != this.phoneNumberValue)
            {
                this.phoneNumberValue = value;
                NotifyPropertyChanged();
            }
        }
    }

好吧,我明白什么? (或相信它)。

发件人:

public event PropertyChangedEventHandler PropertyChanged;

1.- PropertyChanged 是一种方法ProperyChanged 事件 触发时将执行的事件。

怀疑:但是这个方法从来没有实现过……

发件人:

private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

2.- NotifyPropertyChanged 是一种方法。由我们创建,可以有我们想要的任何名称。当属性被修改时,我们会启动这个方法。

问题:此方法是否会触发 ProperyChanged 事件

怀疑:对我来说,正如我在那里看到的那样,没有人启动此事件,但我们创建的方法是在触发时启动。但是由于它没有触发,我们直接启动方法而不是它......

Mixture 最终认为:NotifyPropertyChanged 使用 Hanlder 抛出事件,以便被“上级实体”(示例代码中的绑定源)捕获,后者接收修改后的属性以便可以对其进行更新。那么,如果我想知道哪些元素/类可以感知这类事件,我该怎么办?

我认为最后一个是正确的,但由于我不是专家,而是我在试图理解它和写这个问题时的想法,我希望你能纠正我。

非常感谢!

更新

非常感谢大家!那么,我可以用我想要的方法订阅事件吗?我试过了:

objetos[usados] = new ItemDB();
objetos[usados].PropertyChanged += mensaje();

与:

public async void mensaje(string cadena)
{
    var dlg = new ContentDialog(){
        Title = "My App",
        Content = cadena,
        PrimaryButtonText = "Yes",
        SecondaryButtonText = "No"
    };

    var result = await dlg.ShowAsync();

}

然后VS说:

错误 1 ​​Ninguna sobrecarga 对应“mensaje”与“System.ComponentModel.PropertyChangedEventHandler”委托相一致

翻译:

错误 1 ​​没有一个与“mensaje”对应的重载与“System.ComponentModel.PropertyChangedEventHandler”委托匹配

为什么它不起作用,因为我的事件是用一个字符串 arg 给出的,而mensaje 接收作为参数和字符串?

【问题讨论】:

  • PropertyChanged 是事件处理程序,而不是方法。它实际上存储了一个委托列表(函数,如果你愿意的话),并且调用(实际上是Invoke'ing)PropertyChanged 将调用所有注册的委托。您可以通过以下方式注册代表:customer.PropertyChanged += OnCustomerChanged;。然后,当您从类内部调用 PropertyChanged 时,将调用 OnCustomerChanged
  • 谢谢彼得!更新了一点!
  • PropertyChanged 的类型为 PropertyChangedEventHandler。如果查看它的定义,您会发现它是一个接受两个参数的委托:object(发送者)和PropertyChangedEventArgs(有关更改的属性的信息)。但是,您的 mensaje 方法需要一个 string 参数,因此它不匹配。
  • 谢谢两位!然后我会阅读有关事件的信息。再次感谢彼得的解释^^
  • @Sinatr 为什么这么粗鲁?如果他不知道,那么他可以要求它。这样其他人就可以将他引向具体的主题。

标签: c# events


【解决方案1】:

我建议您在 C# 中查找 EventsDelegates 以进一步阅读。

public event PropertyChangedEventHandler PropertyChanged;

PropertyChanged 是一个 EventHandler,它是一个委托。其他代码可以在这里注册并在委托被调用时执行。

那么 INotifyPropertyChanged 会发生什么:

一些代码(可能是 Xaml 中的绑定)注册 PropertyChanged 事件:

yourobject.PropertyChanged += MethodThatShouldBeCalledWhenThePropertyChanges;

(这是最恰当地在某处自动生成的,因为它是从 xaml 发生的,但您也可以通过这种方式手动生成。)

NotifyPropertyChanged 方法中,事件委托被执行。 它只是执行添加到事件中的所有方法。

所以回答你的问题:

是的,NotifyPropertyChanged 中的代码“触发”了该事件。它调用添加到事件中的每个方法。

任何代码都可以注册事件。

截至您的更新

我再次建议阅读代表。

您可以将委托视为方法接口。它定义了一个方法必须采用特定的参数类型来匹配委托。

PropertyChanged 是 PropertyChangedEventHandler 类型,它接受一个对象和一个 PropertyChangedEventArgs 参数。

所以像这样的任何方法都是合适的:

void MethodName(
Object sender,
PropertyChangedEventArgs e
)

【讨论】:

  • 感谢您的解释!在试图理解它的同时更新了一点=)
  • 感谢您的精彩回答。如果我理解正确,关键是每个具有数据绑定的控件的 MethodThatShouldBeCalledWhenThePropertyChanges (示例方法的名称)是 PropertyChangedEventHandler,如:public event PropertyChangedEventHandler PropertyChanged。 PropertyChanged(this, new PropertyChangedEventArgs(propertyName)) 调用它们中的每一个。
  • @Hong:不确定我是否理解评论:附加到PropertyChanged 事件的每个方法都将被执行。它们中的大多数是绑定的一部分,因此您不会看到代码。该方法将在内部过滤propertyName。但是,是的,它们都被执行了。
  • 这是我的理解。我认为令人困惑的部分是调用的方法是不可见的。
【解决方案2】:

首先,你是对的,NotifyPropertyChanged 是一个用户定义的函数。缩进只是为了避免在使用更多属性时逻辑加倍。其次,NotifyPropertyChanged在事件触发时不会被执行,反之亦然;只要调用NotifyPropertyChanged,就会触发事件。如果绑定了一个合适的控件,可以说,它将消耗事件并可能更新自身。该事件可以看作是其他代码可以注册回调的出口。此外,属性CallerMemberName 是在 .NET 4.5 中引入的。不使用它也可以实现相同的结果,但是对于NotifyPropertyChanged 的每次调用,都必须明确给出属性的名称。

【讨论】:

    猜你喜欢
    • 2016-02-20
    • 2012-12-11
    • 2011-02-18
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多