2012-06-22 20 views
10
Debug.WriteLine(ucFollow.Visible); 
ucFollow.Visible = true; 
Debug.WriteLine(ucFollow.Visible); 

ucFollow es un UserControl personalizado, nada sofisticado. El código anterior imprime:C# UserControl Propiedad visible que no cambia

False 
False 

Lo peor de todo es que este hace cambiar la visibilidad real del control de usuario (es decir ucFollow aparece una vez que el código se llama), pero parece de alguna manera que la propiedad Visible no es ... bueno, visible en el back-end, y no refleja el cambio, incluso si la interfaz de usuario sí lo hace.

Ni siquiera sé por dónde empezar a solucionar este problema. ¿Alguien tiene alguna idea de lo que remotamente podría causar este tipo de locura?

Editar: Se trata de un C# WinForm estándar en Visual Studio 2010.

+0

¿Es esto WinForms, ASP.NET, algo más? –

+0

WinForms, lo siento, debería haber especificado – sichinumi

+15

Bueno, si rompió C# Tengo muchos años, tendrá que arreglarlo. –

Respuesta

24

¡No rompí C#! :)

Resulta que el culpable era la propiedad Form.Visible. Antes de que Form.Visible se establezca en verdadero, todos y cada uno de los controles del formulario serán invisibles (Visible = falso) pase lo que pase.

Sin embargo, aún puede establecer Propiedades visibles: simplemente no tendrán efecto hasta que la propiedad Form.Visible se establezca en verdadero.

En otras palabras, cuando llamé al ucFollow.Visible = true, mi programa lo estaba registrando, sin embargo, en ese punto del código, el Form.Visible principal de ucFollow aún era falso. Por lo tanto, tanto el Depurador como mis instrucciones de impresión reconocieron: "Oye, el formulario padre de este control aún no está visible, por lo que este control no está visible. Período".

Tan pronto como se hizo visible el formulario, todos los cambios surtieron efecto y todo funcionó de maravilla.

Moraleja de la historia: no confíe en las propiedades de Visibilidad de sus controles a menos que el formulario que los contiene ya esté visible y ejecutándose.

+4

Si desea saber si el control * sería * visible (si el control principal estaba visible), puede ver mi pregunta [aquí] (http://stackoverflow.com/questions/5980343/how) -do-i-determine-visibilidad-de-un-control) para la solución – SwDevMan81

+0

puede marcar esto como una respuesta, está perfectamente bien para hacerlo. Otro comportamiento extraño y maravilloso de la visibilidad de los controles (en modo de diseño) es cuando tienes un UserControl que no declaras en InitializeComponent() .. (por alguna razón) ... si abres el formulario, no se muestra el Control ni aparece en la lista desplegable Propiedades de los controles. –

2

Este es el peligro de asumir las propiedades y los campos son la misma cosa. Por supuesto, son muy similares conceptualmente (ese es el punto), pero enfáticamente no son mecánicamente iguales. Echar un vistazo a lo que realmente hace ucFollow.Visible = true: (. Código cortesía de ILSpy)

protected virtual void SetVisibleCore(bool value) 
{ 
    try 
    { 
     HandleCollector.SuspendCollect(); 
     if (this.GetVisibleCore() != value) 
     { 
      if (!value) 
      { 
       this.SelectNextIfFocused(); 
      } 
      bool flag = false; 
      if (this.GetTopLevel()) 
      { 
       if (this.IsHandleCreated || value) 
       { 
        SafeNativeMethods.ShowWindow(new HandleRef(this, this.Handle), value ? this.ShowParams : 0); 
       } 
      } 
      else 
      { 
       if (this.IsHandleCreated || (value && this.parent != null && this.parent.Created)) 
       { 
        this.SetState(2, value); 
        flag = true; 
        try 
        { 
         if (value) 
         { 
          this.CreateControl(); 
         } 
         SafeNativeMethods.SetWindowPos(new HandleRef(this.window, this.Handle), NativeMethods.NullHandleRef, 0, 0, 0, 0, 23 | (value ? 64 : 128)); 
        } 
        catch 
        { 
         this.SetState(2, !value); 
         throw; 
        } 
       } 
      } 
      if (this.GetVisibleCore() != value) 
      { 
       this.SetState(2, value); 
       flag = true; 
      } 
      if (flag) 
      { 
       using (new LayoutTransaction(this.parent, this, PropertyNames.Visible)) 
       { 
        this.OnVisibleChanged(EventArgs.Empty); 
       } 
      } 
      this.UpdateRoot(); 
     } 
     else 
     { 
      if (this.GetState(2) || value || !this.IsHandleCreated || SafeNativeMethods.IsWindowVisible(new HandleRef(this, this.Handle))) 
      { 
       this.SetState(2, value); 
       if (this.IsHandleCreated) 
       { 
        SafeNativeMethods.SetWindowPos(new HandleRef(this.window, this.Handle), NativeMethods.NullHandleRef, 0, 0, 0, 0, 23 | (value ? 64 : 128)); 
       } 
      } 
     } 
    } 
    finally 
    { 
     HandleCollector.ResumeCollect(); 
    } 
} 

Su respuesta se encuentra en algún lugar de ese laberinto atormentado de la lógica.

+0

Tengo la sensación de que mi solución puede vincularse con algo del laberinto de lógica antes mencionado, pero es viernes y no me molesto en encontrarlo. :) – sichinumi

3

el culpable es que controla la propiedad Visible es en realidad una propiedad (con get; set;) y el conjunto asignará al miembro m_Visible interno pero el get verá todos los controles principales y solo devolverá verdadero si todos tienen m_Visible == true

Cuestiones relacionadas