Получить и установить фактический тип объекта с помощью Object.GetType () возможно?

1

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

public static Control GetCtl(this object obj)
{
    //(obj as obj.GetType()) ?
    return (TextBox)obj;
}

Но что, если мне нужно получить один из другого (неизвестного) типа объекта, например TextBox или RichTextBox? Затем я буду использовать это:

private void TextBox1_Click(object sender, EventArgs e)
{
    sender.GetCtl().Select(0, 0);
}

Хотя TextBox и RichTextBox похоже, имеют один и тот же метод Select, когда я пробовал вышеупомянутую GetCtl(), она всегда GetCtl() ошибку. Как это сделать правильно?

Изменить: поскольку вы не можете получить доступ к "завершенному" свойству управления как sender во всех собственных процедурах/методах (т.е. _Click(), _MouseMove()) Я хочу создать функцию, которая может вернуть фактический элемент управления, а не уверен, как объяснить это лучше, но вот как я буду использовать его:

Private void SomeControl_KeyDown(object sender, KeyEventArgs e){
    sender.getCtl().   //<-- so I can access anything here

    (sender as Button).Text = "sometext"  // <-- so I won't have to do this

    //I wish the following would work. But you get the idea
    (sender.GetType())sender.Text = "";
    //or...
    (sender as sender.GetType()).Text = "";
}
Теги:
winforms

1 ответ

2
Лучший ответ

RichTextBox и TextBox оба являются производными от TextBoxBase.

Чтобы сообщить компилятору, что вы хотите рассматривать объект как определенный тип, вы можете выполнить операцию литья. В этом случае вам нужно sender в TextBoxBase а затем вы можете получить доступ к методу Select():

private void TextBox1_Click(object sender, EventArgs e)
{
    var textbox = sender as TextBoxBase;
    if (textbox != null)
        textbox.Select(0, 0);
}

Это использует ключевое слово as, чтобы TextBoxBase объект sender TextBoxBase. Обратите внимание, что вы не можете просто что-то приложить к чему-либо еще. Фактически объект должен быть экземпляром того типа, который вы используете. Если sender не является экземпляром чего-то, полученного из TextBoxBase, операция cast вернет значение null.

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

Если вам действительно нужен метод преобразования отправителя в TextBoxBase, вы можете написать его как:

private TextBoxBase ToTextBoxBase(object sender)
{
    var textbox = sender as TextBoxBase;
    if (textbox == null)
        throw new Exception("The given object is not derived from TextBoxBase");

    return textbox;
}

Вы бы использовали его как:

ToTextBoxBase(sender).Select(0, 0);

Если отправитель не является TextBoxBase, этот вызов будет генерировать исключение "данный объект не является производным от TextBoxBase".

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

Можно создать метод, который вы можете вызвать с помощью этого синтаксиса:

sender.ToTextBoxBase()

Это называется методом расширения. Тем не менее, вы бы расширяли класс System.Object для очень конкретной цели, что не рекомендуется.

  • 0
    Спасибо! Это действительно делает это, но можете ли вы помочь мне с созданием пользовательского метода getCtl() ? Потому что я хочу также использовать его на других элементах управления, чтобы легко получить доступ к методам sender .
  • 0
    Я имею в виду, можете ли вы по-прежнему обращаться к методу объекта / элемента управления, когда операция приведения возвращает null ? Это означает, что это не TextBoxBase а что-то еще
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню