【问题标题】:It is possible to pass data to EventArgs without creating derived class?可以在不创建派生类的情况下将数据传递给 EventArgs 吗?
【发布时间】:2022-02-25 14:10:58
【问题描述】:

我有点困惑。我知道我可以创建从 EventArgs 派生的类,以便拥有自定义事件数据。但是我可以以某种方式使用基类 EventArgs 吗?就像鼠标按钮点击一样,在订阅者方法中,总是有“EventArgs e”参数。我能否以某种方式创建以这种方式传递数据的方法,我的意思是它们将在基本 Eventargs 中传递?

【问题讨论】:

  • 如果你试图在鼠标点击事件中捎带数据,你不仅不能这样做,而且表明你的设计存在问题。
  • 有没有机会澄清为什么这必然是一个设计问题?菜单不能在语义上被视为一堆按钮,其相关事件允许您询问菜单中实际按下了哪个“按钮”?想要通过单击按钮传递额外信息,您违反了什么设计原则?

标签: c# events


【解决方案1】:

您可以通过通用类型方法使用 EventArgs 类。在这个示例中,我将使用 Rect 类作为返回类型:

public EventHandler<Rect> SizeRectChanged;

发起活动:

if(SizeRectChanged != null){
   Rect r = new Rect(0,0,0,0);
   SizeRectChanged(this,r);
}

监听事件:

anyElement.SizeRectChanged += OnSizeRectChanged;

public void OnSizeRectChanged(object sender, Rect e){
    //TODO abything using the Rect class
    e.Left = e.Top = e.Width = e.Height = 50;
}

因此,不需要创建新的事件类或委托,只需创建一个传递特定类型 T 的 EventHandler。

【讨论】:

  • 这看起来不对。 MSDN website example 表明 Rect 或 TEventArg 必须从 EventArgs 继承。除非我有什么误解。
  • Thomas,我也觉得这很混乱。但是 jupi 的建议对我有用。
  • 哇...希望我很久以前就知道这一点。我一直认为,当您声明 EventHandler 时,T 必须派生自 EventArgs。因此,例如,如果我需要在我的事件中发送一个字符串,我将创建一个从 EventArgs 子类化的新类 StringEventArgs。 Thomas Lann 链接到的 MSDN 文档确实说“它的第二个参数派生自 EventArgs 类型并保存事件数据”,这意味着大多数读者不能使用任何任意类。但是编译器似乎不介意 EventHandler ,据我所知,这完全可以正常工作。
  • 在 Microsoft Visual Studio Community 2015 中,这会引发错误:错误 CS0315 类型“float”不能用作泛型类型或方法“EventHandler”中的类型参数“TEventArgs”。没有从 'float' 到 'System.EventArgs' 的装箱转换。
【解决方案2】:

不。 EventArgs 基类只是允许某些标准事件委托类型的一种方式。最终,要将数据传递给处理程序,您需要继承 EventArgs。您可以改用 sender arg,但这应该是触发事件的对象。

【讨论】:

  • 点赞将我引导至 sender 参数,这正是我需要与处理程序进行沟通
【解决方案3】:

是否可以只使用 EventArgs 原始数据类型?绝对地。根据 MSDN:

该类不包含事件数据;它由在引发事件时不将状态信息传递给事件处理程序的事件使用。如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。

http://msdn.microsoft.com/en-us/library/system.eventargs.aspx

    private event TestEventEventHandler TestEvent;
    private delegate void TestEventEventHandler(EventArgs e);

    private void button1_Click(object sender, EventArgs e)
    {
        TestEvent += TestEventHandler;
        if (TestEvent != null)
        {
            TestEvent(new EventArgs());
        }
    }
    private void TestEventHandler(EventArgs e)
    {
        System.Diagnostics.Trace.WriteLine("hi");
    }

你应该这样做吗?我想不出任何理由。如果您想创建自己的点击,您也可以自己实例化 MouseEventArgs

MouseEventArgs m = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, 42, 42, 1);

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 2013-03-03
  • 2013-05-11
  • 1970-01-01
相关资源
最近更新 更多