.NET(C#)事件 - 自定义EventArgs问题

时间:2010-02-03 16:36:36

标签: c# .net events

我有许多与在树中选择的项目相关联的C#自定义事件,然后使用上下文菜单触发对所选项目的某些操作。我开始为每个自定义事件创建一个单独的基于EventArgs的类,以打包事件的必要数据。

在后视中,我意识到我的大多数(可能是所有)自定义事件都需要至少传递树选择所代表的底层对象列表。有些事件可能还需要额外的数据。

考虑到这一点,我想知道以下任何一种是否是可接受的做法?

  • 对多个事件(那些只需要传递对象列表的事件)使用相同的基于EventArgs的自定义类。显然,这应该有效,但似乎脱离了一些用于连接事件机制的推荐命名约定。

  • 创建一个基类,它包装我经常需要的对象列表,然后从中派生其他类,因为需要额外的数据。

  • 也许还有别的东西?

目前,我只有少数自定义事件,但需要添加更多。由于我看到每个事件所需数据出现的模式,我希望在继续之前有更好的计划。

感谢您的任何建议。

4 个答案:

答案 0 :(得分:5)

我之前已经完成了这条路。我第二次想到了一个包含公共数据的基本事件类。如果没有事件将直接使用它,请将基类设置为内部,以避免向用户公开不必要的对象。拥有基类还允许您以后添加更多事件数据。由于该类是内部的,因此它的用户在外部不受更改的影响。

答案 1 :(得分:3)

.NET框架中有很多这样的例子。沿着同样的路线做某事是非常一致的。这是一对夫妇:

  • System.ComponentModel.ProgressChangedEventArgs (向派生类型提供ProgressPercentageUserState
    • System.Net.DownloadProgressChangedEventArgs
    • System.Net.UploadProgressChangedEventArgs
    • System.Windows.Documents.Serialization.WritingProgressChangedEventArgs
  • System.ComponentModel.CancelEventArgs (将Cancel成员提供给派生类型)
    • Microsoft.VisualBasic.ApplicationServices.StartupEventArgs
    • System.ComponentModel.DoWorkEventArgs
    • System.Configuration.SettingChangingEventArgs
    • System.Drawing.Printing.PrintEventArgs
    • System.Web.UI.WebControls.DetailsViewDeleteEventArgs
    • System.Web.UI.WebControls.DetailsViewInsertEventArgs
    • System.Web.UI.WebControls.DetailsViewModeEventArgs
    • System.Web.UI.WebControls.DetailsViewPageEventArgs
    • System.Web.UI.WebControls.DetailsViewUpdateEventArgs
    • System.Web.UI.WebControls.EntityDataSourceChangingEventArgs
    • Literally 50 more of these

编辑:

我可能会使用这样的类(不是抽象)。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

public class CollectionEventArgs<T> : EventArgs
{
    public static readonly CollectionEventArgs<T> Empty = new CollectionEventArgs<T>();

    public CollectionEventArgs(params T[] items)
    {
        this.Items = new ReadOnlyCollection<T>(items);
    }

    public CollectionEventArgs(IEnumerable<T> items)
    {
        this.Items = new ReadOnlyCollection<T>(items.ToArray());
    }

    public ReadOnlyCollection<T> Items
    {
        get;
        private set;
    }
}

答案 2 :(得分:1)

我会选择一和二。创建一个可用于大多数事件的基类,然后从该类派生出需要其他事件的事件。如果你看看它们构建方式的.NET库。

请确保使用适当的命名约定。基类不应包含特定事件的名称,只有在一个事件中使用的类才应引用事件的名称。基类可能包含控件的名称。

答案 3 :(得分:1)

你的意思是

public class EventArgs<TValue> : EventArgs
{
    public TValue Value { get; }

    /* ... */
}

我可以用Value作为我喜欢的地方吗?

是的,我很高兴使用这样的东西。我不认为这是一个问题。