Mar*_*ijn 33 c# event-handling
我不熟悉基于事件的编程.基本上,我仍然磕磕绊绊.我正在努力设置一些东西,但即使有了教程,我也无法绕过它.我想做的(用语言)如下:
我有一个属性更改的数据对象.我在属性的setter中注意到这一点,并且想要引发属性已更改的事件.
在其他地方(完全不同的类),我想知道这个对象的属性已经改变,并采取一些行动.
现在我确定这是一个很常见的场景,但是我的谷歌让我失望了.我只是不了解http://msdn.microsoft.com/en-us/library/ms743695.aspx.
我有这个:
public class ChattyClass {
private int someMember;
public event PropertyChangedEventHandler PropertyChanged;
public int SomeMember {
get {
return this.someMember;
}
set {
if (this.someMember != value){
someMember = value;
// Raise event/fire handlers. But how?
}
}
}
public class NosyClass{
private List<ChattyClass> myChatters;
public void addChatter(ChattyClass chatter){
myChatters.add(chatter);
// Start listening to property changed events
}
private void listner(){
// I want this to be called when the PropertyChangedEvent is called
Console.WriteLine("Hey! Hey! Listen! A property of a chatter in my list has changed!");
}
}
Run Code Online (Sandbox Code Playgroud)
我怎么做才能把它连接起来?
关于评论指向我回到链接:
在示例中,我看到:
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白的是:
PropertyChanged(this, new PropertyCHangedEventArgs(name))Sty*_*xxy 36
你必须解雇这个事件.在MSDN上的示例中,他们创建了一个受保护的方法OnPropertyChanged来处理这个问题(并避免重复代码).
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
Run Code Online (Sandbox Code Playgroud)
这个方法的作用是查看是否分配了事件处理程序(如果没有分配,你只需要调用它,你就会得到一个NullReferenceException).如果指定了一个,则调用此事件处理程序.提供的事件处理程序必须具有PropertyChangedEventHandler委托的签名.这个签名是:
void MyMethod(object sender, PropertyChangedEventArgs e)
Run Code Online (Sandbox Code Playgroud)
其中第一个参数必须是类型对象,并表示触发事件的对象,第二个参数包含此事件的参数.在这种情况下,您自己的类会触发事件,从而this作为参数提供sender.第二个参数包含已更改的属性的名称.
现在,为了能够对事件的触发作出反应,您必须为该类分配一个事件处理程序.在这种情况下,您必须在addChatter方法中指定它.除此之外,您必须先定义您的处理程序.在你的工作中,NosyClass你必须添加一个方法来做到这一点,例如:
private void chatter_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("A property has changed: " + e.PropertyName);
}
Run Code Online (Sandbox Code Playgroud)
如您所见,此方法对应于我之前解释过的签名.在第二个参数中,您将能够找到已更改的参数的信息.最后要做的是添加事件处理程序.现在在你的addChatter方法中,你必须分配这个:
public void AddChatter(ChattyClass chatter)
{
myChatters.Add(chatter);
// Assign the event handler
chatter.PropertyChanged += new PropertyChangedEventHandler(chatter_PropertyChanged);
}
Run Code Online (Sandbox Code Playgroud)
我建议你阅读一些关于.NET/C#事件的内容:http://msdn.microsoft.com/en-us/library/awbftdfh.我认为阅读/学习之后,事情会更清楚.
如果您想快速测试它,可以在pastebin上找到一个控制台应用程序(只需复制/粘贴到新的控制台应用程序中).
使用较新版本的C#,您可以内联对事件处理程序的调用:
// inside your setter
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyProperty)));
Run Code Online (Sandbox Code Playgroud)
您还可以使用Fody PropertyChanged之类的东西自动生成必要的代码(访问其GitHub页面的链接,带样本).
Val*_*ale 12
您查找的链接是MVVM模式和WPF.它不是一般的C#实现.你需要这样的东西:
public event EventHandler PropertyChanged;
public int SomeMember {
get {
return this.someMember;
}
set {
if (this.someMember != value) {
someMember = value;
if (PropertyChanged != null) { // If someone subscribed to the event
PropertyChanged(this, EventArgs.Empty); // Raise the event
}
}
}
Run Code Online (Sandbox Code Playgroud)
...
public void addChatter(ChattyClass chatter) {
myChatters.add(chatter);
chatter.PropertyChanged += listner; // Subscribe to the event
}
// This will be called on property changed
private void listner(object sender, EventArgs e){
Console.WriteLine("Hey! Hey! Listen! A property of a chatter in my list has changed!");
}
Run Code Online (Sandbox Code Playgroud)
如果您想知道哪些属性已更改,您需要将事件定义更改为:
public event PropertyChangedEventHandler PropertyChanged;
Run Code Online (Sandbox Code Playgroud)
并将调用更改为:
public int SomeMember {
get {
return this.someMember;
}
set {
if (this.someMember != value){
someMember = value;
if (PropertyChanged != null) { // If someone subscribed to the event
PropertyChanged(this, new PropertyChangedEventArgs("SomeMember")); // Raise the event
}
}
}
private void listner(object sender, PropertyChangedEventArgs e) {
string propertyName = e.PropertyName;
Console.WriteLine(String.Format("Hey! Hey! Listen! a {0} of a chatter in my list has changed!", propertyName));
}
Run Code Online (Sandbox Code Playgroud)
为什么不这只是调用PropertyChanged(这个,新的PropertyCHangedEventArgs(name))
因为如果没有人为事件附加处理程序,则该PropertyChanged对象返回null.因此,在调用它之前,您必须确保它不为null.
PropertyChanged在哪里被分配?
在"监听器"类中.
例如,您可以在其他类中编写:
ChattyClass tmp = new ChattyClass();
tmp.PropertyChanged += (sender, e) =>
{
Console.WriteLine(string.Format("Property {0} has been updated", e.PropertyName));
};
Run Code Online (Sandbox Code Playgroud)
作业是什么样的?
在C#中,我们使用赋值运算符+=和-=事件.我建议阅读以下文章,以了解如何使用匿名方法表单(上面的示例)和"旧"表单编写事件处理程序.
| 归档时间: |
|
| 查看次数: |
83861 次 |
| 最近记录: |