2011-07-29 14 views
5

Tengo problemas con las propiedades de una forma base que no mantiene el estado en una forma heredada.Las propiedades personalizadas definidas en forma base pierden su estado en forma heredada al reconstruir

Medio Ambiente:

  • Visual Studio 2010 Ultimate Service Pack 1: Versión 10.0.40219.1 SP1Rel
  • .Net Framework: Versión 4.0.30319 SP1Rel
  • Windows 7 Ultimate

A continuación, se muestra el código fuente y los pasos para reproducir:

using System; 
using System.ComponentModel; 
using System.Windows.Forms; 

namespace Test 
{ 
    public partial class BaseForm : Form 
    { 
     [DefaultValueAttribute(true)] 
     public bool ControlVisible 
     { 
      get 
      { 
       return this.checkBox1.Visible; 
      } 
      set 
      { 
       this.checkBox1.Visible = value; 
      } 
     } 

     [DefaultValueAttribute(false)] 
     public bool ControlChecked 
     { 
      get 
      { 
       return this.checkBox1.Checked; 
      } 
      set 
      { 
       this.checkBox1.Checked = value; 
      } 
     } 

     public BaseForm() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

En lo anterior, las propiedades predeterminadas coinciden con [DefaultValueAttribute], es decir, en InitializeComponent() checkBox1.Visible se establece en true y checkBox1.Checked es falso. Estas son las configuraciones predeterminadas para el control cuando se colocan en el formulario.

entonces creado la siguiente forma hereditaria:

using System; 
using System.ComponentModel; 
using System.Windows.Forms; 

namespace Test 
{ 
    public partial class Form1 : BaseForm 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

Emisión y pasos para reproducir:

  1. Al abrir Form1 en el diseñador de las propiedades son los en estado siguiente.

    Estado: ControlChecked = False - ControlVisible = verdadera (negrita)

    ControlVisible se establece en Verdadero como era de esperar, sin embargo, está en negrita. El [DefaultValueAttribute] se establece en true en el formulario base, por lo que esperaba que esta propiedad no estuviera en negrita.

  2. ahora cambio ControlVisible a Falso en el diseñador. El negrita se apaga.

    Estado: ControlChecked = False - ControlVisible = False

  3. ahora reconstruir el proyecto y el código en Form1 Obtiene regenerado. La propiedad ControlVisible revierte a True en negrita.

    Estado: ControlChecked = False - ControlVisible = verdadera (negrita)

  4. ahora cambio ControlChecked de Falso a Verdadero y se convierte en negrita como se esperaba.

    Estado: ControlChecked = verdadera (negrita) - ControlVisible = verdadera (negrita)

  5. reconstruyo el proyecto y ningún cambio.

    Estado: ControlChecked = verdadera (negrita) - ControlVisible = verdadera (negrita)

  6. ahora puedo cambiar la propiedad de ControlVisible de verdadera a Falso y reconstruir de nuevo el proyecto . ControlVisible volvió a verdadero en negrita.

    Estado: ControlChecked = verdadera (negrita) - ControlVisible = verdadera (negrita)

ControlChecked parece que está funcionando como se esperaba. ControlVisible mantiene volviendo a verdadero cuando se establece en falso y el negrita se invierte. Me parece que de alguna manera no se reconoce [DefaultAttributeValue] de true en el formulario base.

Actualización: Revisado para corregir un error y más exactamente para aislar el problema.

Actualización: Si fijo checkBox1.Visible = false en el constructor de BaseForm, entonces todo funciona como se esperaba. Por lo tanto, parece que el problema es que se reconozca DefaultValueAttribute de verdadero en la propiedad personalizada en el formulario heredado.

Respuesta

2

Está su checkBox1 privado en la clase base? Si no es así, debería ser así, porque el diseñador serializará ambos setters (uno para checkBox1.Visible y el otro para ControlVisible), y solo el orden de la serialización determinará el estado final, que es malo.

También, busque en el método InitializeControls generados automáticamente en el archivo Form1.designer.cs, no se establece explícitamente las propiedades personalizadas a sus valores por defecto?

Por último, intente utilizar ShouldSerialze and Reset y vea si obtiene un comportamiento diferente.

Editar

He recreado el problema a nivel local y unido uno VS ejemplo para depurar otra.La primera vez que la propiedad ControlVisible fue evaluada por VS devolvió false porque checkBox1.Visible (la fuente getter) era false. Cuando se creó y se mostró el control de casilla de verificación real, y la ventana Propiedades se desplazó para mostrar ControlVisible su valor se evaluó nuevamente y devolvió true que es el valor predeterminado, sin embargo, parece que VS ya etiquetó esa propiedad como modificada, dado que es valor inicial era diferente al valor predeterminado. Esto puede ser un error en VS.

He creado una simple demostración del efecto:

public BaseForm() 
    { 
     InitializeComponent(); 
     _testValue = false; 
    } 

    private bool _testValue; 

    [DefaultValue(true)] 
    public bool TestProperty 
    { 
     get { return _testValue; } 
     set { _testValue = value; } 
    } 

    protected override void OnVisibleChanged(EventArgs e) 
    {    
     _testValue = true; 
     base.OnVisibleChanged(e); 
    } 
} 

Cuando heredar lo anterior BaseForm la TestPropery se comporta exactamente igual que el ControlVisible en su ejemplo, por lo que creo que es un error en VS.

La solución a su problema es el uso de un campo respaldo bool simple como un ayudante, ya que no es fiable checkBox1.Visible:

public BaseForm() 
    { 
     InitializeComponent(); 
     checkBox1.Visible = _controlVisible = true; 
    } 

    private bool _controlVisible; 

    [DefaultValue(true)] 
    public bool ControlVisible 
    { 
     get { return _controlVisible; } 
     set { _controlVisible = checkBox1.Visible = value; } 
    } 
+0

checkBox1 es privado en la clase base. Form1.designer.cs establece explícitamente ControlVisible cuando se establece en "verdadero", que se invierte. Esta es la propiedad predeterminada y no la configura cuando es "falsa". Probé ShouldSerialize y Reset y esto no hizo diferencia. El formulario heredado tiene el valor predeterminado invertido en la propiedad personalizada ControlVisible. De alguna manera, no reconoce la configuración DefaultAttribute en la clase base y también parece ignorar el ShouldSerialize/Reset. – Elan

+1

Extraño, hice una demostración local y funciona como usted describió. Cuando un campo de bool privado es la fuente de ControlVisible, funciona como se esperaba, pero cuando la fuente es checkBox1.Visible, no funciona. –

+0

Cuando configuro ControlVisible = false y cambio [DefaultAttribute (false)] en la propiedad. Entonces la forma heredada también funciona como se esperaba. Parece que se reduce a [DefaultAttribute (true)] sin tomar. – Elan

4

Su propiedad ControlVisible siempre se establece en false:

[DefaultValueAttribute(true)] 
    public bool ControlVisible 
    { 
     get 
     { 
      return this.checkBox1.Visible; 
     } 
     set 
     { 
      this.checkBox1.Visible = false; 
     } 
    } 

Su método set debería ser:

this.checkBox1.Visible = value; 
+0

ojo del tigre! :) – Reniuz

+0

¡Muy nítido! Wow, eso fue embarazoso. Rectifiqué el código y eso resolvió un par de anomalías: queda un problema. – Elan

Cuestiones relacionadas