2016-07-26 126 views
0

我使用C#,我想从一个类中触发事件:C#触发事件

所以,如果一个类的Price财产被改变,那么事件onPriceChanged(类外)应该被解雇。 但是,我收到一个错误:

The name 'onPriceChanged' does not exist in the current context

我该如何解决这个问题? (我想我可以在事件处理程序传递给通过构造方法的类...但如果可能的话我宁愿不要在事件处理程序传递给类)

这里是我的代码:

using System; 

public delegate void delEventHandler(); 

class clsItem 
{ 
    //private static event delEventHandler _show; 
    private delEventHandler _show; 
    private int _price; 

    public clsItem() //Konstruktor 
    { 
     _show += new delEventHandler(Program.onPriceChanged); // error here : The name 'onPriceChanged' does not exist in the current context 
    } 

    public int Price 
    { 
     set 
     { 
      _price = value; 
      _show.Invoke(); //trigger Event when Price was changed 
     } 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
     clsItem myItem = new clsItem(); 
     myItem.Price = 123; //this should trigger Event "onPriceChanged" 
    } 

    //EventHandler 
    public static void onPriceChanged() 
    { 
     Console.WriteLine("Price was changed"); 
    } 
} 
+1

'_show + =新delEventHandler(Program.onPriceChanged);' – 2016-07-26 12:13:40

+0

onPriceChanged是在不同的类(计划)。 – ohadinho

+0

你正在做什么事情的完全相反。 clsItem类不应该知道谁在监听它的事件。换句话说,'clsItem'应该公开一个公共事件,并且在创建新的实例之后,您应该在'Main'方法中附加处理程序。 – Groo

回答

2

你这样做是错误的 - 你试图从类中附加事件处理程序,并且显然不能访​​问Program.onPriceChanged方法!

您应该公开您的事件,并附上来自客户端代码(Program)的事件处理程序。

class clsItem 
{ 
    //private static event delEventHandler _show; 
    private delEventHandler _show; 
    private int _price; 

    public clsItem() //Konstruktor 
    { 

    } 

    public event delEventHandler Show 
    { 
     add { _show += value; } 
     remove { _show -= value; } 
    } 

    public int Price 
    { 
     set 
     { 
      _price = value; 
      _show?.Invoke(); //trigger Event when Price was changed 
     } 
    } 
} 

和:

clsItem myItem = new clsItem(); 
myItem.Show += onPriceChanged; 
myItem.Price = 123; //this now does trigger Event "onPriceChanged" 

活生生的例子:http://rextester.com/WMCQQ40264

+0

不应该检查'_show'是否为空?如果没有附加事件处理程序,是不是会抛出一个空引用异常? –

+0

@ChrisDunaway - yep。 – Jamiec

0

这里是做的更传统的方式你想要什么:

public delegate void delEventHandler(); 

class clsItem 
{ 
    public event delEventHandler Show; 
    private int _price; 

    public clsItem() //Konstruktor 
    { 
    } 

    public int Price 
    { 
     set 
     { 
      _price = value; 
      Show?.Invoke(); //trigger Event when Price was changed 
     } 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
     clsItem myItem = new clsItem(); 
     myItem.Show += onPriceChanged; 
     myItem.Price = 123; //this should trigger Event "onPriceChanged" 
    } 

    //EventHandler 
    public static void onPriceChanged() 
    { 
     Console.WriteLine("Price was changed"); 
    } 
} 

注意clsItem不再知道是谁正在订阅它的活动。所有它关心的是通知任何恰好被订阅的听众。 clsItemonPriceChanged方法之间不再有依赖关系。

0

你处理事件的方式不是一个好习惯。我们使用Events的原因是将我们创建的对象与他们需要调用的方法分离。

例如,如果您想要创建另一个相同类型的对象(clsItem),并在价格更改后调用另一个方法,则会遇到麻烦。所以我建议这个代码,而不是目前的一个:

using System; 

public delegate void delEventHandler(); 

class clsItem 
{ 
    public event delEventHandler PriceChanged; 
    private int _price; 

    public clsItem() //Konstruktor 
    { 

    } 

    public int Price 
    { 
     set { 
       if(value!=_price) // Only trigger if the price is changed 
       { 
       _price = value; 
       if(PriceChanged!=null) // Only run if the event is handled 
       { 
        PriceChanged(); 
       } 
       } 
      } 
    } 
}  

class Program 
{ 
    static void Main() 
    { 
     clsItem myItem = new clsItem(); 
     myItem.PriceChanged += new delEventHandler(onPriceChanged); 
     myItem.Price = 123; //this should trigger Event "PriceChanged" and call the onPriceChanged method 
    } 

    //EventHandler 
    public static void onPriceChanged() 
    { 
     Console.WriteLine("Price was changed"); 
    } 
}