Есть ли способ сохранить метод расширения в исходном объекте? - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть класс UserControl класса (говорит MyDataGrid), который наследуется от DataGrid стороннего производителя (говорит ItsDataGrid). В этом случае я создаю только элемент управления MyDataGrid, но в нем нет MyDataGridColumn и MyDataGridCell, которые наследуются от ItsDataGridColumn и ItsDataGridCell

Мой случай заключается в том, что я создаю некоторый метод расширения для OurDataGridColumn, который добавит некоторый обработчик события к Itsumnata (оператором + =)

Если мы вызываем метод расширения только один раз, это хорошо. Но если мы вызываем метод расширения более одного раза, количество событий будет складываться. (В моем случае это все в порядке, потому что оно только изменяет примитивное свойство в событии, и последнее событие вступит в силу, наконец. Но все же хочу знать, есть ли лучший способ сделать это).

В настоящий момент я могу придумать несколько подходов:

  1. Очистка всех обработчиков событий в OurDataGridColumn при каждом вызове метода расширения. Но похоже, что мы можем сделать это только путем отражения, чтобы получить непубличную переменную c ( Как удалить все обработчики событий из события ). Кроме того, в приведенном выше случае это хорошо известный элемент управления Win Button по умолчанию, но я использую сторонний.

  2. У меня есть свой собственный класс MyDataGridColumn, который наследуется от ItsDataGridColumn, с дополнительной переменной для хранения добавленного дескриптора события. Таким образом, каждый раз, когда я вызываю функцию расширения (действительно, в этом случае функция расширения не требуется, поскольку мы можем добавить функцию непосредственно в класс MyDataGridColumn), она может удалить обработчик события (с помощью - = handler).

  3. Нужно где-то хранить добавленный обработчик событий, чтобы его можно было удалить позже. Но так как я использую метод расширения, я не могу сохранить добавленный обработчик событий, потому что у него нет свойства расширения. Если я сохраню его на уровне c уровня другого класса, он будет на уровне c уровня, но не на уровне экземпляра. Конечно, у меня может быть словарь на уровне c, но мне нужно подумать об уникальном ключе для идентификации каждого столбца.

Для 1 это довольно грязный способ сделать это , Кроме того, он может непреднамеренно удалить некоторые другие обработчики событий

. Для 2 требуется достаточно много рефакторинга, чего я бы хотел избежать

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

Любая помощь очень ценится.

1 Ответ

0 голосов
/ 08 апреля 2020

Обновляя код из предыдущего ответа , мы можем либо удалить обработчик, прежде чем добавить его (потому что удаление не завершится неудачей, если нет обработчиков):

private void UltraGrid1_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
    var column = e.Layout.Bands[YOUR_BAND_INDEX].Columns[YOUR_COLUMN_INDEX];
    column.Style = Infragistics.Win.UltraWinGrid.ColumnStyle.URL;
    var editor = column.Editor as FormattedLinkEditor;

    //remove the handler before add, to prevent adding multiple handlers
    editor.LinkClicked -= this.Editor_LinkClicked;

    editor.LinkClicked += this.Editor_LinkClicked;
}

Или мы можем использовать одно из свойств Tag элементов управления, чтобы помнить, что мы добавили обработчик для этого. Элементы управления Windows имеют свойство Tag, которое является объектом и предназначено для хранения данных общего назначения, связанных с элементом управления. Если мы сохраним строку в теге и проверим ее позже, мы можем избежать многократного добавления обработчика. Возможно, как один из них:

private void UltraGrid1_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
    var column = e.Layout.Bands[YOUR_BAND_INDEX].Columns[YOUR_COLUMN_INDEX];

    //did we add the handler already?
    if(column.Tag != null && column.Tag.ToString() == "handlerIsAdded")
      return;

    column.Style = Infragistics.Win.UltraWinGrid.ColumnStyle.URL;

    var editor = column.Editor as FormattedLinkEditor;
    editor.LinkClicked += this.Editor_LinkClicked;

    column.Tag = "handlerIsAdded"; //remember for next time, so we don't add handler again
}

Я не знаю, хотите ли вы добавить это на уровне столбца или на уровне редактора; Я никогда не работал с элементом управления сеткой, который вы используете. Если для столбца есть только один элемент управления редактором, и он не обновляется, вы также можете использовать элемент управления редактора:

private void UltraGrid1_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
    var column = e.Layout.Bands[YOUR_BAND_INDEX].Columns[YOUR_COLUMN_INDEX];
    column.Style = Infragistics.Win.UltraWinGrid.ColumnStyle.URL;
    var editor = column.Editor as FormattedLinkEditor;

    //did we add the handler already?
    if(editor.Tag != null && editor.Tag.ToString() == "handlerIsAdded")
      return;

    editor.LinkClicked += this.Editor_LinkClicked;

    editor.Tag = "handlerIsAdded"; //remember for next time
}
...