簡體   English   中英

啟動具有訪問者的事件

[英]Launch an event that has accessors

如何啟動具有以下訪問器的事件:

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

如果這是正常事件,我會通過以下方式啟動它:

CanExecuteChanged(sender, EventArgs..). 

但在這里它不起作用 - 我只能這樣做

CanExecuteChanged +=..

附加方法做事件 - 但我無法啟動它。

此外,一些關於這個主題的文件將不勝感激。 謝謝。

編輯該事件來自在WPF中實現ICommand的類。 沒有什么可以顯示:)。 並且沒有 - CommandManager.RequerySuggested(this,EventArgs.Empty); 不起作用。

EDIT2不知道該說些什么 - 即使正確調用add方法,Jon的例子也應該有效 - 當我嘗試調用事件時 - 它是null:|。 我可能會刪除帶有訪問器的事件。

我認為你有與代表混淆的事件。 只有暴露事件的類才能引發它......其他人只能訂閱 - 取消訂閱它。 如果要從聲明事件的類中調用事件,它應該像常規委托一樣工作。

我可以在Events vs Delegates上找到的最佳頁面。 讀起..

你可以發一個更大的片段......似乎有些不對勁......

殺手更新

我想我終於看到了你的問題以及如何解決它。 簡答: 如果您編寫自己的訪問器,它不知道要調用的委托的名稱。 如果你不這樣做......編譯器會添加已知名稱的私有委托,因此可以調用它

這段代碼顯示了我的意思。 這篇MSDN文章向我展示了光明 很棒的問題伙計......我失去了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!");
        }
}

該事件只是訂閱和取消訂閱另一個事件。 如果您希望調用您的訂閱者(並且只有您的訂閱者 - 而不是與其他活動分開的訂閱者),則需要單獨保留您的訂閱者。 例如,您可以將代碼更改為:

private EventHandler canExecuteChanged;

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

好的,我發現如果我想觸發那個事件,你必須這樣做:

CommandManager.InvalidateRequerySuggested();.

哇,剛才有類似的問題。 幫助我理解的答案有點像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();
        }
    }
}

如果你向上面的ss添加訪問器,它將不會編譯:

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上進行了測試,並且規格是最新的,我猜)

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

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

/編輯:好的,我沒注意到CommandManager是一個框架類。 在這種情況下,你顯然不想做我提出的建議。 Jon的解決方案就是要點:你必須跟蹤自己的事件並調用它(例如作為代表)。 與Jon的例子一致,調用看起來像這樣:

canExecuteChanged(sender, EventArgs.Empty);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM