События .NET (C #) - пользовательский вопрос EventArgs - PullRequest
5 голосов
/ 03 февраля 2010

У меня есть несколько пользовательских событий C #, которые связаны с элементами, выбранными в дереве, а затем с контекстным меню, используемым для запуска некоторых действий с выбранными элементами. Я начал создавать отдельный класс на основе EventArgs для каждого настраиваемого события, чтобы упаковать необходимые данные для этого события.

Однако, задним ходом я понимаю, что большинству (может быть, всем) моих пользовательских событий нужно будет пройти хотя бы список базовых объектов, представленных выделением дерева. Некоторые события, вероятно, также потребуют дополнительных данных.

Имея это в виду, мне интересно, является ли любое из следующего приемлемой практикой?

  • Используйте один и тот же пользовательский класс на основе EventArgs для нескольких событий (тех, которые просто нуждаются в передаче списка объектов). Очевидно, что это должно сработать, но, похоже, отрывается от некоторых рекомендуемых соглашений об именах, используемых для подключения механизма событий.

  • Создайте базовый класс, который оборачивает мой часто необходимый список объектов, и затем извлекайте из него дополнительные классы по мере необходимости в дополнительных данных.

  • Может быть, что-то еще целиком?

В настоящее время у меня есть только несколько пользовательских событий, но мне нужно добавить больше. Поскольку я вижу, что в отношении данных, необходимых для каждого события, возникает определенная схема, я хотел бы иметь более точный план, прежде чем продолжить.

Спасибо за любой совет.

Ответы [ 4 ]

5 голосов
/ 03 февраля 2010

Я прошел эту дорогу раньше. Я пошел с вашей второй идеей иметь базовый класс событий, который оборачивает общие данные. Если ни одно событие не будет использовать его напрямую, сделайте базовый класс внутренним, чтобы избежать предоставления ненужных объектов пользователям. Наличие базового класса также позволяет добавлять больше данных о событиях позднее. Поскольку класс является внутренним, его пользователи внешне не подвержены изменениям.

3 голосов
/ 08 февраля 2010

Есть много примеров этого в .NET Framework. Было бы вполне логично сделать что-то в том же духе. Вот пара:

  • System.ComponentModel.ProgressChangedEventArgs (обеспечивает ProgressPercentage и UserState для производных типов)
    • 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
    • Буквально 50 больше из них

Edit:

Я мог бы использовать такой класс (, а не аннотация).

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;
    }
}
1 голос
/ 03 февраля 2010

Вы имеете в виду что-то вроде

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

    /* ... */
}

?

Где я могу использовать как Value все, что мне нравится?

Да, я с радостью использую такойвещь.Я не думаю, что это проблема.

1 голос
/ 03 февраля 2010

Я бы пошел как на один, так и на два. Создайте базовый класс, который вы можете использовать для большинства ваших событий, а затем наследовать от этого класса для событий, которые требуют чего-то еще. Если вы посмотрите на библиотеки .NET, это способ, которым они были построены.

Просто убедитесь, что вы используете соответствующее соглашение об именах. Базовый класс не должен включать имя определенного события, только класс, который используется только в одном событии, должен ссылаться на имя события. Базовый класс, вероятно, будет включать имя вашего элемента управления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...