Transmitir objeto de remitente en el controlador de eventos mediante GetType ().

StackOverflow https://stackoverflow.com/questions/634112

  •  10-07-2019
  •  | 
  •  

Pregunta

Tengo un controlador de eventos para un cuadro de texto, así como para un RichTextBox. El código es idéntico, pero

En el controlador # 1 lo hago:

RichTextBox tb = (RichTextBox)sender

En el controlador # 2 en consecuencia:

TextBox tb = (TextBox)sender

Al hacerlo, puedo manipular completamente el control de envío. Lo que quiero saber es cómo puedo enviar el objeto de envío a Textbox o RichTextbox según su tipo usando

sender.GetType().Name

y luego cree el control en tiempo de ejecución y trabaje con él. De esa manera solo necesito una función de controlador de eventos: menos código, menos errores, más fácil de mantener y SECO :-)

¿Fue útil?

Solución

Dependiendo de las propiedades que necesite, puede convertir el remitente como TextBoxBase ya que tanto TextBox como RichTextBox heredan de esa subclase.

Otros consejos

Nunca tienes que lanzar. Solía ??pensar de la misma manera cuando comencé, este 'patrón' es incorrecto y no es realmente lógico.

Su mejor opción es usar algo como:

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

Sé que esta es una publicación muy antigua, pero en Framework 4 puede emitir el remitente como Control:

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

Tenga en cuenta que solo puede hacer referencia a controles que todos los controles diferentes tienen en común (es decir, Texto).

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";
}

La conversión solo se puede realizar en tiempo de compilación y, por lo tanto, debe conocer los tipos a los que desea emitir en tiempo de compilación. Por lo tanto, un tipo de tiempo de ejecución (tal como lo devuelve GetType ()) no se puede utilizar al transmitir.

Si está buscando polimorfismo, puede acceder a la propiedad Nombre a través de la reflexión. Sin embargo, no iría de esa manera solo para poder reutilizar los controladores de eventos.

Si desea escribir con firmeza, una clase base común o interfaz en los dos remitentes es el único camino a seguir.

En lugar del nombre de tipo, podría usar ' es '.

Si solo quiere saber el tipo y no necesita una referencia de objeto:

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

Sin embargo, generalmente desea el objeto: C # 7 tiene una buena sintaxis que le permite probar y obtener el valor en línea:

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

También puede usar una variable temporal en línea para manejar el reparto por usted.

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

Si el código es idéntico, ¿necesita preocuparse? Me pregunto si enviar a Control no te daría todo lo que necesitas ...

Un controlador complejo no es necesariamente mejor que varios controladores simples. De cualquier manera, si tiene para ir por esta ruta, " como " / " es " es preferible (no depende de cadenas, etc.):

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

si no desea repetir el código, puede convertir ambos controles, refactorizar las acciones comunes a un método separado que tome TextBoxBase como argumento. Y en su caso, los controladores convierten los controles a System.Windows.Forms.TextBoxBase ya que ambos controles se derivan de TexbBoxBase y llaman al método.

Tenga en cuenta que si necesita propiedades específicas de cualquiera de estos controles, esta refactorización no funcionará.

Versión genérica del código anterior:

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

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

Utilizado como:

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

No perfecto, pero útil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top