启动具有访问者的事件

本文关键字:事件 访问者 启动 | 更新日期: 2023-09-27 17:47:47

如何启动具有以下访问器的事件:

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

如果这是一个正常的事件,我会通过以下方式启动:

CanExecuteChanged(sender, EventArgs..). 

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

CanExecuteChanged +=..

附加一个方法做事件-但我不能启动它。

此外,如能提供一些有关该主题的文件,将不胜感激。谢谢

编辑该事件来自WPF中实现ICommand的类。没有什么可展示的了:)。没有——指挥官。RequerySuggested(此,EventArgs.Empty);不起作用。

EDIT2不知道该说什么-Jon的例子应该还有效,即使add方法调用正确-当我试图调用事件时,它是空的:|。我可能会的删除带有访问者的事件。

启动具有访问者的事件

我认为您将事件与委托混为一谈。只有公开事件的类才能引发它…其他类只能订阅或取消订阅它。如果你从声明事件的类中调用事件,它应该像常规委托一样工作。

我能找到的关于活动与代表的最佳页面。阅读。。

你能发布一个更大的片段吗。。好像有什么不对劲。。

杀手更新

我想我终于明白了你的问题以及如何解决它。简短回答:如果您编写自己的访问器,它不知道要调用的委托的名称。如果你不这样做。。编译器添加已知名称的私有委托,因此能够调用它

这个代码片段展示了我的意思。MSDN的这篇文章向我展示了光明。很好的问题,伙计。。我输了30分钟。投票支持:)

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();.

您必须直接调用底层事件。在你的情况下,看起来这将是:
<blockquote>CommandManager.RequerySuggested(sender, EventArgs.…)</blockquote>

/编辑:好的,我没有注意到CommandManager是一个框架类。在这种情况下,你显然不想按照我的建议去做。Jon的解决方案很关键:你必须跟踪自己的事件并调用它(例如作为代表)。按照Jon的例子,调用看起来是这样的:
canExecuteChanged(sender, EventArgs.Empty);

哇,刚才也有类似的问题。帮助我理解的答案有点像吉树的。

同样从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. 带有accessors=>的事件,我们无法调用(在规范中找不到这一点,为什么,也许我错过了它)(我只在VisualStudio2005上测试过,我想规范是最新的)