了解PropertyChanged机制的工作原理(工作流程)

时间:2015-01-20 10:36:53

标签: c# events

澄清: 1.- 我不知道如果它有一个特定的名称或单词用英语或编程俚语引用它,那么这可能是一个重复的帖子,因为我可以& #39;看看它。

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 final think:NotifyPropertyChanged使用Hanlder抛出事件,以便被"上级实体捕获#34; (示例代码中的绑定源),它接收修改后的属性以便可以更新它。然后,如果我想知道哪些元素/类可以知道这类事件,我该怎么办?

我认为这最后一个是正确的,但是因为我不是专家,而是我的想法,同时试图理解它并写下这个问题,我希望你纠正我。

非常感谢!

已更新

非常感谢大家!然后,我可以用我想要的方法来约束事件吗?我试过了:

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'重合con' System.ComponentModel.PropertyChangedEventHandler' delegado

翻译:

  

错误1没有人过载对应于' mensaje'与' System.ComponentModel.PropertyChangedEventHandler'匹配代表

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

3 个答案:

答案 0 :(得分:11)

我建议您在C#中查找事件代表以便进一步阅读。

public event PropertyChangedEventHandler PropertyChanged;

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

所以INotifyPropertyChanged会发生什么:

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

yourobject.PropertyChanged += MethodThatShouldBeCalledWhenThePropertyChanges;

(这是最适合在某处自动生成的,因为它是从xaml发生的,但你也可以手动这样做。)

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

所以回答你的问题:

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

任何代码都可以注册活动。

自您的更新

我再次建议阅读代表。

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

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

所以这样的方法都适合:

void MethodName(
Object sender,
PropertyChangedEventArgs e
)

答案 1 :(得分:1)

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

答案 2 :(得分:0)

我认为这篇文章:WPF Data Binding - INotifyPropertyChanged是一个关于PropertyChanged机制的非常好的解释。