2011-08-22 115 views
1

我希望我的C#代码在值赋给我的对象时调用一个事件。如何编写触发器?

我到底需要去做些什么?

class MyClass { 

    ManualResetEvent mre; 

    public MyClass() { 
    mre = new ManualResetEvent(false); 
    Data = null; 
    } 

    public object Data { get; set; } 

    void DataSet(object sender, EventArgs e) { 
    Console.WriteLine("object Data has been set."); 
    mre.Set(); 
    } 

} 

代表似乎并不是我所需要的。一个事件,也许?如果是这样的话,我会怎么写这样的事件?

MyClass mc; 

void processA() { 
    mc = new MyClass(); 
    mc.Data = GetDataFromLongProcess(); 
} 

回答

5
private object data; 
public object Data { 
    get { return data;} 
    set { 
     if(value != data) { 
      data = value; 
      OnDataChanged(); 
     } 
    } 
} 
protected virtual void OnDataChanged() { 
    EventHandler handler = DataChanged; 
    if(handler != null) handler(this, EventArgs.Empty); 
} 
public event EventHandler DataChanged; 

然后勾任何代码到事件DataChanged。例如:

MyClass mc = ... 
mc.DataChanged += delegate { 
    Console.WriteLine("new data! wow!"); 
}; 
+0

谢谢。我知道这很简单。我只是有一个脑袋。 – jp2code

+0

DataChanged方法声明中需要更改什么,以便我可以编写一个处理器方法,该方法使用自定义数据类型? (例如'if(handler!= null)handler(this,new MyEventArgs(Data));'(我已经写了MyEventArgs'类,我不知道如何声明'DataChanged'方法来实现它。 – jp2code

+1

@ jp2code你可以声明它为'public eventHandler' DataChanged;' – dlev

1

,你可以执行INotifyPropertyChanged(这或多或少是一个事件),或者你可以把你的类动作(触发),并调用该方法,whenn属性改变。

只是不要使用自动属性,而是一个具体的setter,并从那里调用你的事件/触发器。

2

如果您希望在属性设置为触发一个事件,你会做这样的事情:

public event Action OnDataChanged; 

protected object _data = null; 
public object Data 
{ 
    get { return _data; } 
    set 
    { 
     _data = value; 
     if(OnDataChanged != null) 
      OnDataChanged(); 
    } 
} 

,那么只需在连线事件处理程序到你的对象,像这样:

mc = new MyClass(); 
mc.OnDataChanged += delegate() { Console.WriteLine("It changed!"); }; 
mc.Data = SomeValue(); 
+1

在大多数C#引用中,'OnFoo'是一个方法(通常是'protected virtual'),它调用*'event'命名为'Foo' - 不是事件本身的名称,当然这只是约定而不是规则,还要注意*严格地说*你应该在空检查之前将字段捕获到变量中,以避免线程边缘条件,可能会导致一个'NullReferenceException' –

+0

好点,老实说,我没有写足够的事件,已经违反了良好的惯例呢= D – Tejs

+0

其实,就*绑定*来说,有一个很好的理由来跟随约定:'PropertyDescriptor'将*检查*名为'* Changed'(而不是'On * Changed')的事件并使用它来支持完整的数据绑定。这也适用于默认的'PropertyDescriptor' API的任何其他用途。 –

2

我认为你正在以事件为基础的模式走上正轨。也看看观察者模式(这是对.NET代表和骨子里事件的基础上,我的理解):

http://www.dofactory.com/Patterns/PatternObserver.aspx

但底线,作为其他有用的答案为止(格雷维尔先生的实施)表明,你将不得不有代码IN让它挂钩。唯一的选择是轮询变化的价值,这对我来说很不好。

1

从概念上讲,您应该在您的类中定义一个事件,并在您的属性集块中,使用必要的参数调用该事件以确定发生的事情。

1
public event SomeDelegateThatTakesIntAsParameter myEvent; 
void SetData(int data) 
{ 
    if(myEvent!= null) 
    myEvent(data) 
} 
相关问题