Подтвердить что ты не робот

Отдать объект отправителя в обработчик событий с помощью GetType().

У меня есть обработчик событий для текстового поля, а также для RichTextBox. Код идентичен, но

В обработчике # 1 я делаю:

RichTextBox tb = (RichTextBox)sender

В обработчике # 2 соответственно:

TextBox tb = (TextBox)sender

Сделав так, я могу полностью управлять передающим элементом управления. Я хочу знать, как я могу передать объект отправки в текстовое поле или RichTextbox в соответствии с его типом, используя

sender.GetType().Name

а затем создать элемент управления во время выполнения и работать с ним. Таким образом, мне нужна только одна функция обработчика событий: меньше кода, меньше ошибок, проще в обслуживании и DRY: -)

4b9b3361

Ответ 1

В зависимости от того, какие свойства вам нужны, вы можете отправить отправителя как TextBoxBase, так как TextBox и RichTextBox наследуются от этого подкласса.

Ответ 2

Вам никогда не нужно бросать. Я привык думать так же, как только начал, этот "шаблон" неверен и не совсем логичен.

Лучше всего использовать что-то вроде:

if (sender is TextBox)
{
  TextBox tb = (TextBox)sender;
}
else if (sender is RichTextBox)
{
  RichTextBox rtb = (RichTextBox)sender;
}
else
{
  // etc
}

Ответ 3

Я знаю, что это очень старый пост, но в Framework 4 вы можете отдать отправителя в качестве элемента управления:

Control cntrl = (Control)sender;
cntrl.Text = "This is a " + sender.GetType().ToString();

Обратите внимание, что вы можете ссылаться на элементы управления, которые имеют общие элементы управления (например, текст).

Ответ 4

RichTextBox textbox = sender as RichTextBox;
if (textbox != null)
{
   // do stuff as a rtb
   textbox.Text = "I'm a rtb";
   return;
}

TextBox textbox = sender as TextBox;
if (textbox != null)
{
   // do stuff as a textbox
   textbox.Text = "I'm a textbox";
}

Ответ 5

Кастинг может выполняться только во время компиляции и, следовательно, вам нужно знать типы, которые вы хотите использовать во время компиляции. Таким образом, тип выполнения (возвращаемый GetType()) не может использоваться при кастинге.

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

Если вам нужна сильная типизация, единственным базовым классом или интерфейсом для двух отправителей является единственный способ.

Ответ 6

Вместо имени типа вы можете использовать 'is', если вы просто хотите знать тип и не нуждаетесь в ссылке на объект.

if (sender is RichTextBox)
{
    // ...
}
else if (sender is TextBox)
{
    // ...
}

Изменить: однако, как указано в комментарии, вам обычно нужен oobject: С# 7 имеет хороший синтаксис, который позволяет вам тестировать и получать значение inline:

if (sender is RichTextBox richTextBox)
{
    richTextBox.Text = "I am rich";
}
else if (sender is TextBox textBox)
{
    textBox.Text = "I am not rich";
}

Ответ 7

Если код идентичен, вам нужно заботиться? Интересно, не отбрасывает ли Control все, что вам нужно...

Один сложный обработчик не обязательно лучше, чем несколько простых обработчиков. В любом случае, если вам нужно пройти этот маршрут, "как" / "is" предпочтительнее (он не зависит от строк и т.д.):

TextBox tb = sender as TextBox;
if(tb!=null) {/* TextBox specific code */}
...

Ответ 8

Если вы не хотите повторять код, вы можете использовать оба элемента управления, реорганизовать общие действия на отдельный метод, который принимает TextBoxBase в качестве аргумента. И в вашем случае обработчики преобразовывают элементы управления в System.Windows.Forms.TextBoxBase, поскольку оба элемента управления производятся из TexbBoxBase и вызывают метод.

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

Ответ 9

Общая версия приведенного выше кода:

public static void CastAndUse<T>(object item, Action<T> action) where T : class
{
    T thing = item as T;

    if (thing != null)
    {
        action(thing);
    }
}

Используется как:

CastAndUse(sender, new Action((foo) => foo = bar));

Не идеально, но удобно.

Ответ 10

Вы также можете использовать встроенную временную переменную для обработки броска для вас.

if (sender is RichTextBox tb)
{
    // ... //
} 
else if (sender is TextBox tb)
{
    // ... //
}