2009-01-19 19 views
8

En mi aplicación, estoy ejecutando el mismo winform en diferentes contextos para controlar la visibilidad de botones, enabeling de campos de texto y el texto del encabezado de winform. La forma en que decidí hacer esto es simplemente pasando una cadena al constructor de formulario y verificarlo con un par de instrucciones if que a su vez contienen los ajustes de winform deseados.Llamada de miembro virtual en el constructor

if (formContext == "add") 
{ 
    Text = "Add member"; 
} 
if (formContext == "edit") 
{ 
    Text = "Change role"; 
    userTextBox.Enabled = false; 
    searchButton.Visible = false; 
} 

Esto funciona bien, sin embargo las palabras clave "texto" Obtener una blue Squigly línea agregada por ReSharper con el siguiente mensaje: Call Viritual en el constructor. ¿Es esto un problema potencial o simplemente algún tipo de mensaje ReSharper demasiado entusiasta?

Cualquier aclaración o sugerencia para mejorar mi implementación sería muy apreciada.

Respuesta

9

Call virtual en la clase base ctor podría causar algo de lógica para ejecutar en la subclase antes de llamar al subclase ctor (y por lo tanto antes de que el objeto tenga la oportunidad de inicializarse a un estado coherente).

Es solo un recordatorio para que sepa que está haciendo algo que podría causar un comportamiento desagradable inesperado.

+0

Sí ... esto es lo que yo pensaba. Alguna sugerencia sobre cómo podría hacer esto mejor. La estabilidad es la prioridad número uno en este proyecto y preferiría evitar posibles comportamientos inesperados. – Sakkle

+0

¿Quiere decir sugerencias además de no llamar a métodos virtuales en su ctor de clase base? :-) En esta situación, podría usar el enlace de datos para vincular la propiedad Text del formulario a un campo de cadena en una clase de modelo GUI que contendría la lógica necesaria para decidir qué debería decir la barra de título. – mookid8000

+0

Sí ... probablemente podría, aunque no sabría por dónde empezar, y supongo que tendría que hacer lo mismo para el botón y el campo de texto. – Sakkle

6

Además de las respuestas existentes, para las formas que podría añadir un controlador de eventos de carga:

Load += delegate 
{ 
    if (formContext == "add") 
    { 
     Text = "Add member"; 
    } 
    if (formContext == "edit") 
    { 
     Text = "Change role"; 
     userTextBox.Enabled = false; 
     searchkButton.Visible = false; 
    } 
}; 
+0

Esta parece ser la solución más fácil y mejor para lo que estoy tratando de lograr, sin tener que reescribir una gran cantidad de código. Sí ... soy perezoso: P – Sakkle

0

yo sugeriría que volver a escribir la clase de la siguiente manera:

public partial class Form1 : Form 
{ 
    public enum FormContextMode 
    { 
     Add, 
     Edit 
    } 

    private FormContextMode m_mode = FormContextMode.Add; 

    public Form1(FormContextMode mode) 
    { 
     InitializeComponent(); 
     m_mode = mode; 
     Load += delegate { UpdateForm(); }; 
    } 

    private void UpdateForm() 
    { 
     if(m_mode == FormContextMode.Add) 
     { 
      Text = "Add member";  
     } 
     else if(m_mode == FormContextMode.Edit) 
     { 
      Text = "Change role"; 
      userTextBox.Enabled = false; 
      searchkButton.Visible = false; 
     } 
    } 
} 
+0

Ahaaa ... dulce :) – Sakkle

+0

No necesita suscribirse al evento de carga propio, simplemente anule el método OnLoad. –

+0

Sí, estoy de acuerdo con Ilya: mejor sobrecargar el método, entonces no tendrá que recordar darse de baja del evento + (y esta es una afirmación de intuición) probablemente más rápido. – ng5000

3

Sólo sellar su clase.

+0

favor relacione ... – Sakkle

+1

http://msdn.microsoft.com/en-us/library/88c54tsw(VS.71).aspx Una clase sellada no se puede heredar, para ello no hay posibilidad de una clase derivada anulando el miembro virtual. – ng5000

Cuestiones relacionadas