2008-10-16 32 views
5

我怎麼能推出具有這樣存取的事件:啓動有一個事件訪問

public event EventHandler CanExecuteChanged 
    { 
     add 
     { 
     CommandManager.RequerySuggested += value; 
     } 
     remove 
     { 
     CommandManager.RequerySuggested -= value; 
     } 
    } 

如果它是一個正常的事件中,我將通過啓動它:

CanExecuteChanged(sender, EventArgs..). 

但這裏不工作 - 我只能做

CanExecuteChanged +=.. 

附加的方法做事件 - 但我不能啓動。

也有關於這個問題的一些文件將不勝感激。 謝謝。

EDIT 事件是從WPF實施ICommand的類。沒有什麼更多的顯示:)。 而不是 - CommandManager.RequerySuggested(this,EventArgs.Empty);不起作用。

EDIT2不知道該說什麼 - 即使add方法調用正確 - 當我嘗試調用事件 - 它是null:|時,Jon的示例應該工作了。我可能會 刪除訪問器事件。

+0

找到了問題。如果你正在包裝一個委託,你必須直接調用委託,而不是像通常那樣進行事件。見下面的帖子。 – Gishu 2008-10-16 12:36:06

回答

3

這一事件只是訂閱,並從另一個事件退訂。如果你想要你的用戶(和只有你的訂戶 - 而不是單獨的其他事件)被調用,你需要分開持有你的訂戶。舉例來說,你可以將代碼更改爲類似:

private EventHandler canExecuteChanged; 

public event EventHandler CanExecuteChanged 
{ 
    add 
    { 
     CommandManager.RequerySuggested += value; 
     canExecuteChanged += value; 
    } 
    remove 
    { 
     CommandManager.RequerySuggested -= value; 
     canExecuteChanged -= value; 
    } 
} 
0

您必須直接調用基礎事件。在你的情況下,它看起來好像這將是:

<blockquote>CommandManager.RequerySuggested(sender, EventArgs.…)</blockquote> 

/編輯:好吧,我沒注意到CommandManager是一個框架類。在這種情況下,你顯然不想按照我的建議去做。喬恩的解決方案是關鍵的:你必須跟蹤自己的事件並調用它(例如作爲委託)。在與Jon的例子保持一致,調用應該是這樣的:

canExecuteChanged(sender, EventArgs.Empty); 
4

我覺得你有與代表混淆事件。只有暴露事件的類可以提升它...其他人只能訂閱 - 取消訂閱它。如果從聲明事件的類中調用事件,它應該像常規代理一樣工作。

我可以在Events vs Delegates找到的最佳網頁。讀了..

你可以發佈一個更大的片斷..有些事情似乎不對勁..

殺手更新

我想,我終於看到你的問題,以及如何解決它。 簡答:如果您編寫自己的訪問器,它不知道要調用的委託的名稱。如果你不......編譯器添加已知名稱的私人代理並因此能夠調用它

此代碼片段顯示了我的意思。這MSDN article showed me the light。很好的問題夥計..我失去了30分鐘。 Upvoted :)

public class Hash1 
    { 

     private EventHandler myHomeMadeDelegate; 
     public event EventHandler FancyEvent 
     { 
      add 
      { 
       //myDelegate += value; 
       myHomeMadeDelegate = (EventHandler)Delegate.Combine(myHomeMadeDelegate, value); 
      } 
      remove 
      { 
       //myDelegate -= value; 
       myHomeMadeDelegate = (EventHandler)Delegate.Remove(myHomeMadeDelegate, value); 
      } 
     } 
     public event EventHandler PlainEvent; 


     public Hash1() 
     { 
      FancyEvent += new EventHandler(On_Hash1_FancyEvent); 
      PlainEvent += new EventHandler(On_Hash1_PlainEvent); 

      // FancyEvent(this, EventArgs.Empty); //won't work:What is the backing delegate called? I don't know 
      myHomeMadeDelegate(this, EventArgs.Empty); // Aha! 
      PlainEvent(this, EventArgs.Empty); 
     } 

     void On_Hash1_PlainEvent(object sender, EventArgs e) 
     { 
      Console.WriteLine("Bang Bang!"); 
     } 

     void On_Hash1_FancyEvent(object sender, EventArgs e) 
     { 
      Console.WriteLine("Bang!"); 
     } 
} 
+0

該死的..我實際上發現了那篇文章,但它沒有足夠的代碼片斷:)所以我繼續前進。 另外,喬恩解釋幾乎相同的東西只有更短:)。但是,謝謝你的更多細節。頂部:P – sirrocco 2008-10-16 12:37:59

1

好吧,我發現,如果我想要觸發事件,你必須做的:

CommandManager.InvalidateRequerySuggested();. 
0

哇,剛剛過類似的問題。幫助我理解的答案有點像Gishu的

從C#規格, http://www.microsoft.com/en-us/download/details.aspx?id=7029

此外,在「10.8.1現場般的事件,」它說:「當編譯一個類似字段的事件時,編譯器會自動創建存儲空間來保存委託,」

規格還說:

因此,窗體的實例事件聲明:

class X 
{ 
    public event D Ev; 
} 

可以被編譯到的東西相當於:

class X 
{ 
    private D __Ev; // field to hold the delegate 

    public event D Ev { 
     add { 
     lock(this) { __Ev = __Ev + value; } 
     } 

     remove { 
     lock(this) { __Ev = __Ev - value; } 
     } 
    } 
} 

如果你做的東西像下面的代碼,編譯器編譯它成功:

namespace ConsoleApplication1 
{  
    class Program 
    { 
     public event EventHandler ss; 

     Program() 
     { 
      if (null != ss) 
      { 
       ss(this, EventArgs.Empty) ; 

      } 
     } 

     static void Main(string[] args) 
     { 
      new Program(); 
     } 
    } 
} 

而如果你在上面添加訪問器,它將不會編譯:

namespace ConsoleApplication1 
{  
    class Program 
    { 
     public event EventHandler ss 
     { 
      add { } 
      remove { } 
     } 

     Program() 
     { 
      if (null != ss) 
      { 
       ss(this, EventArgs.Empty) ; 

      } 
     } 

     static void Main(string[] args) 
     { 
      new Program(); 
     } 
    } 
} 

有兩種類型的事件證明了這裏

  1. 現場般的事件=>我們可以調用
  2. 事件與存取=>我們不能調用(爲什麼不能在規範覺得這也許,我錯過了)(並且只在Visual Studio 2005上測試過,規格是最新的,我猜)