了解 PropertyChanged 机制的工作原理(工作流程)
Understanding how PropertyChanged mechanism works (workflow)
说明:
1.- 我不知道 这是否有一个特定的名称或词来引用它在英语或编程俚语中,所以也许这可能是重复的 post,因为我我看不下去了。
2.- 我对这些东西完全是新手,我从未使用过处理程序,所以这是问题的一部分。
我正在尝试了解 NotifyPropertyChanged 机制的工作原理。基于:INotifyPropertyChanged,重点举例。 (我看的是西班牙文的,上面你可以把它改成英文原版,如果不自动改的话。
下面我就把让我疑惑的主要代码摘下来,试着分析一下。希望你能告诉我哪里(如果存在)我错了以及我不明白的地方。 让我们关注实现接口的class。
// 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 是一种方法。由我们创建,可以有我们想要的任何名称。此方法将在 us 修改 属性 时启动。
问题:该方法是否触发ProperyChanged事件?
疑问:对我来说,正如我在那里看到的那样,没有人启动此事件,但是我们创建的方法在触发时启动。但是因为它不会触发,我们直接启动方法而不是它...
Mixture 最终认为:NotifyPropertyChanged 使用 Hanlder 抛出事件,以便被 "superior entity"(示例代码中的绑定源)捕获,后者按顺序接收修改后的 属性可以更新它。那么,如果我想知道哪些elements/classes可以知道这种事件,我该怎么办?
我认为最后一个是正确的,但由于我不是专家,而是我在尝试理解它和写这个问题时的想法,我希望你能纠正我。
非常感谢!
已更新
非常感谢大家!那么,我可以用我想要的方法订阅事件吗?我试过:
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 说:
Error 1 Ninguna sobrecarga correspondiente a 'mensaje' coincide con el 'System.ComponentModel.PropertyChangedEventHandler' delegado
已翻译:
Error 1 No one overload corresponding to 'mensaje' matches with 'System.ComponentModel.PropertyChangedEventHandler' delegate
为什么它不起作用,因为我的事件带有一个字符串参数,而 mensaje
作为参数和字符串接收?
首先,你是对的,NotifyPropertyChanged
是一个用户自定义函数。缩进只是为了避免在使用更多属性时逻辑加倍。第二,NotifyPropertyChanged
不会在事件触发时执行,而是反过来;一旦 NotifyPropertyChanged
被调用,事件就会被触发。如果绑定了合适的控件,可以说它将消耗事件并可能更新自身。该事件可以看作是其他代码可以在其上注册回调的出口。此外,属性 CallerMemberName
是在 .NET 4.5 中引入的。不使用它也可以获得相同的结果,但是对于 NotifyPropertyChanged
的每次调用,都必须明确给出 属性 的名称。
我建议您在 C# 中查找 Events 和 Delegates 以进一步阅读。
public event PropertyChangedEventHandler PropertyChanged;
PropertyChanged 是一个 EventHandler,它是一个委托。其他代码可以在这里注册并在调用委托时执行。
那么 INotifyPropertyChanged 会发生什么:
一些代码(可能是 Xaml 中的绑定)注册了 PropertyChanged 事件:
yourobject.PropertyChanged += MethodThatShouldBeCalledWhenThePropertyChanges;
(这是在某处自动生成的最恰当的方法,因为它发生在 xaml,但您也可以通过这种方式手动生成。)
在 NotifyPropertyChanged 方法中,事件委托被执行。
它只是执行添加到事件中的所有方法。
所以回答你的问题:
是的,NotifyPropertyChanged "triggers" 事件中的代码。它调用添加到事件中的每个方法。
任何代码都可以注册事件。
截至您的更新:
我再次推荐阅读代表。
您可以将委托视为方法接口。它定义了一个方法必须采用特定的参数类型来匹配委托。
PropertyChanged 的类型为 PropertyChangedEventHandler,它接受一个对象和一个 PropertyChangedEventArgs 参数。
所以像这样的任何方法都适用:
void MethodName(
Object sender,
PropertyChangedEventArgs e
)
说明: 1.- 我不知道 这是否有一个特定的名称或词来引用它在英语或编程俚语中,所以也许这可能是重复的 post,因为我我看不下去了。
2.- 我对这些东西完全是新手,我从未使用过处理程序,所以这是问题的一部分。
我正在尝试了解 NotifyPropertyChanged 机制的工作原理。基于:INotifyPropertyChanged,重点举例。 (我看的是西班牙文的,上面你可以把它改成英文原版,如果不自动改的话。
下面我就把让我疑惑的主要代码摘下来,试着分析一下。希望你能告诉我哪里(如果存在)我错了以及我不明白的地方。 让我们关注实现接口的class。
// 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 是一种方法。由我们创建,可以有我们想要的任何名称。此方法将在 us 修改 属性 时启动。
问题:该方法是否触发ProperyChanged事件?
疑问:对我来说,正如我在那里看到的那样,没有人启动此事件,但是我们创建的方法在触发时启动。但是因为它不会触发,我们直接启动方法而不是它...
Mixture 最终认为:NotifyPropertyChanged 使用 Hanlder 抛出事件,以便被 "superior entity"(示例代码中的绑定源)捕获,后者按顺序接收修改后的 属性可以更新它。那么,如果我想知道哪些elements/classes可以知道这种事件,我该怎么办?
我认为最后一个是正确的,但由于我不是专家,而是我在尝试理解它和写这个问题时的想法,我希望你能纠正我。
非常感谢!
已更新
非常感谢大家!那么,我可以用我想要的方法订阅事件吗?我试过:
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 说:
Error 1 Ninguna sobrecarga correspondiente a 'mensaje' coincide con el 'System.ComponentModel.PropertyChangedEventHandler' delegado
已翻译:
Error 1 No one overload corresponding to 'mensaje' matches with 'System.ComponentModel.PropertyChangedEventHandler' delegate
为什么它不起作用,因为我的事件带有一个字符串参数,而 mensaje
作为参数和字符串接收?
首先,你是对的,NotifyPropertyChanged
是一个用户自定义函数。缩进只是为了避免在使用更多属性时逻辑加倍。第二,NotifyPropertyChanged
不会在事件触发时执行,而是反过来;一旦 NotifyPropertyChanged
被调用,事件就会被触发。如果绑定了合适的控件,可以说它将消耗事件并可能更新自身。该事件可以看作是其他代码可以在其上注册回调的出口。此外,属性 CallerMemberName
是在 .NET 4.5 中引入的。不使用它也可以获得相同的结果,但是对于 NotifyPropertyChanged
的每次调用,都必须明确给出 属性 的名称。
我建议您在 C# 中查找 Events 和 Delegates 以进一步阅读。
public event PropertyChangedEventHandler PropertyChanged;
PropertyChanged 是一个 EventHandler,它是一个委托。其他代码可以在这里注册并在调用委托时执行。
那么 INotifyPropertyChanged 会发生什么:
一些代码(可能是 Xaml 中的绑定)注册了 PropertyChanged 事件:
yourobject.PropertyChanged += MethodThatShouldBeCalledWhenThePropertyChanges;
(这是在某处自动生成的最恰当的方法,因为它发生在 xaml,但您也可以通过这种方式手动生成。)
在 NotifyPropertyChanged 方法中,事件委托被执行。 它只是执行添加到事件中的所有方法。
所以回答你的问题:
是的,NotifyPropertyChanged "triggers" 事件中的代码。它调用添加到事件中的每个方法。
任何代码都可以注册事件。
截至您的更新:
我再次推荐阅读代表。
您可以将委托视为方法接口。它定义了一个方法必须采用特定的参数类型来匹配委托。
PropertyChanged 的类型为 PropertyChangedEventHandler,它接受一个对象和一个 PropertyChangedEventArgs 参数。
所以像这样的任何方法都适用:
void MethodName(
Object sender,
PropertyChangedEventArgs e
)