2016-07-26 172 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"); 
    } 
}