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

ucFollow è un UserControl personalizzato, niente di eccezionale. Il codice precedente viene stampato:C# UserControl Visible Property Not Changing

False 
False 

parte peggiore è, questo fa commutare la visibilità effettiva dell'UserControl (cioè ucFollow viene visualizzata una volta che questo codice viene chiamato), ma sembra in qualche modo che la proprietà Visible non è ... beh, visibile sul backend e non riflette il cambiamento, anche se l'interfaccia utente stessa.

Non so nemmeno dove iniziare a risolvere questo problema. Qualcuno ha qualche idea su cosa possa causare a distanza questo tipo di follia?

Edit: Questo è con uno standard C# WinForm in Visual Studio 2010.

+0

È questo WinForms, ASP.NET, qualcos'altro? –

+0

WinForms, mi spiace, dovrei aver specificato – sichinumi

+15

Beh, se hai rotto C#, ho deciso di risolverlo. –

risposta

24

Non ho rotto C#! :)

Risulta che il colpevole era la proprietà Form.Visible. Prima che Form.Visible sia impostato su true, tutti i controlli del modulo saranno invisibili (Visible = false) indipendentemente da cosa.

Tuttavia, è ancora possibile set Proprietà visibili: non avranno effetto finché la proprietà Form.Visible non è impostata su true.

In altre parole, quando ho chiamato ucFollow.Visible = true, il mio programma lo stava effettivamente registrando, tuttavia, a quel punto del codice, il genitore di ucFollow Form.Visible era ancora falso. Pertanto, sia il debugger che le mie istruzioni di stampa hanno riconosciuto: "Ehi, la forma genitoriale di questo controllo non è ancora visibile, quindi questo controllo non è visibile."

Non appena il modulo è stato reso visibile, tutte le modifiche hanno avuto effetto e tutto ha funzionato alla grande.

Morale della trama: non fare affidamento sulle proprietà Visibilità dei controlli a meno che il modulo che li contiene sia già visibile e in esecuzione.

+4

Se vuoi sapere se il controllo * sarebbe * visibile (se il controllo genitore era visibile), puoi vedere la mia domanda [qui] (http://stackoverflow.com/questions/5980343/how -do-i-verify-visibility-of-a-control) per la soluzione – SwDevMan81

+0

è possibile contrassegnare questo come una risposta, è perfettamente ok per farlo. Un altro strano e meraviglioso comportamento della visibilità dei controlli (in modalità progettazione) è quando si ha un UserControl che non si dichiara in InitializeComponent() .. (per quale motivo mai) ... se si apre il modulo il Controllo non viene mostrato né è elencato nell'elenco a discesa Proprietà dei controlli. –

2

Questo è il pericolo di assumere proprietà e campi sono la stessa cosa. Ovviamente sono molto simili allo concettualmente (questo è il punto) ma non lo sono in modo altrettanto meccanico. Date un'occhiata a ciò che realmente fa ucFollow.Visible = true: (. Codice per gentile concessione di 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(); 
    } 
} 

La risposta sta nel quel labirinto tormentata della logica.

+0

Ho la sensazione che la mia soluzione possa essere collegata a qualcosa nel già citato labirinto di logica, ma è un venerdì e non posso essere disturbato a trovarlo. :) – sichinumi

3

il colpevole è che controlla la proprietà Visible è in realtà una proprietà (con get; set;) e il set assegnerà al membro interno m_Visible ma il get controllerà tutti i controlli parent e restituirà true solo se tutti hanno m_Visible == true