2009-06-03 10 views
6

Questo è un problema .net con winforms, non asp.net.L'associazione dati funziona con controllo invisibile?

Ho un modulo di Windows con diverse schede. Ho impostato i binding di dati di tutti i controlli quando il modulo è stato caricato. Ma ho notato che i collegamenti dei dati dei controlli nella seconda scheda non funzionano. Questi collegamenti funzionano solo quando il modulo viene caricato e quando seleziono la seconda scheda. Questo mi porta il sospetto: i binding dei dati funzionano solo quando i controlli associati diventano visibili.

Chiunque può dirmi se questo è vero o no? Non è difficile provarlo ma vorrei sapere qualche conferma.

Grazie

risposta

8

Sei corretto. Un controllo con associazione a dati non viene aggiornato finché il controllo non viene reso visibile.

L'unico riferimento che posso trovare al momento è this MSDN thread.

+0

Wow. Immagino di essere sempre andato per i dati tramite l'origine dati - non avevo davvero idea che i binding funzionassero davvero solo quando il controllo era visibile. – overslacked

+1

Ho avuto lo stesso problema, vedere http://stackoverflow.com/questions/9828153 –

+0

Personalmente lo considero una funzionalità. – nawfal

0

Questo non è qualcosa che ho incontrato direttamente. Tuttavia, potresti riscontrare un problema con lo BindingContext. Senza ulteriori dettagli è difficile dirlo, ma se fossi in te, imposterei un punto di interruzione e assicurarmi che i controlli siano tutti vincolati nello stesso contesto.

4

Il problema ha a che fare con il comportamento di TabControl. Vedi Microsoft bug report. Ho postato una soluzione per quel problema che sottoclasse TabControl e "Iniatalizza" tutte le pagine di tabulazione quando viene creato il controllo o viene creato l'handle. Di seguito è riportato il codice per la soluzione alternativa.

public partial class TabControl : System.Windows.Forms.TabControl 
{ 
    protected override void OnHandleCreated(EventArgs e_) 
    { 
     base.OnHandleCreated(e_); 
     foreach (System.Windows.Forms.TabPage tabPage in TabPages) 
     { 
      InitializeTabPage(tabPage, true, Created); 
     } 
    } 

    protected override void OnControlAdded(ControlEventArgs e_) 
    { 
     base.OnControlAdded(e_); 
     System.Windows.Forms.TabPage page = e_.Control as System.Windows.Forms.TabPage; 
     if ((page != null) && (page.Parent == this) && (IsHandleCreated || Created)) 
     { 
      InitializeTabPage(page, IsHandleCreated, Created); 
     } 
    } 

    protected override void OnCreateControl() 
    { 
     base.OnCreateControl(); 
     foreach (System.Windows.Forms.TabPage tabPage in TabPages) 
     { 
      InitializeTabPage(tabPage, IsHandleCreated, true); 
     } 
    } 

    //PRB: Exception thrown during Windows Forms data binding if bound control is on a tab page with uncreated handle 
    //FIX: Make sure all tab pages are created when the tabcontrol is created. 
    //https://connect.microsoft.com/VisualStudio/feedback/details/351177 
    private void InitializeTabPage(System.Windows.Forms.TabPage page_, bool createHandle_, bool createControl_) 
    { 
     if (!createControl_ && !createHandle_) 
     { 
      return; 
     } 
     if (createHandle_ && !page_.IsHandleCreated) 
     { 
      IntPtr handle = page_.Handle; 
     } 
     if (!page_.Created && createControl_) 
     { 
      return; 
     } 
     bool visible = page_.Visible; 
     if (!visible) 
     { 
      page_.Visible = true; 
     } 
     page_.CreateControl(); 
     if (!visible) 
     { 
      page_.Visible = false; 
     } 
    } 
} 
+0

Che cosa fa esattamente "IntPtr handle = page_.Handle", considerando che il valore non è utilizzato? – Michael

+0

Forza l'handle da creare –

+0

Grazie. Ho pensato che fosse qualcosa del genere.L'ho provato, btw, ma non ha funzionato per me. I miei controlli venivano aggiunti mentre IsHandleCreated e Created erano ancora falsi. Immagino che qualche ritocco possa coprire quel caso, ma ho preso una strada diversa: dopo aver eseguito tutti i binding, ho trovato tutti i controlli associati e ho aggiunto un gestore VisibleChanged a quelli invisibili, che faranno ciò di cui ho bisogno quando diventano visibili. – Michael

0

Abbiamo riscontrato un problema simile. Stiamo provando a scrivere su 2 campi invisibili e vincolati in modo da poter modificare il formato che scriviamo nel nostro set di dati. Funziona correttamente quando gli oggetti sono visibili, ma smette di funzionare quando la proprietà visible è stata modificata in false.

per andare in giro, ho aggiunto il seguente codice:

  // Stop our screen flickering. 
     chSplitContainer.Panel2.SuspendLayout(); 
     // Make the bound fields visible or the binding doesn't work. 
     tbxValueCr.Visible = true; 
     tbxValueDb.Visible = true; 

     // Update the fields here. 
     <DO STUFF> 

     // Restore settings to how they were, so you don't know we're here. 
     tbxValueCr.Visible = false; 
     tbxValueDb.Visible = false; 
     chSplitContainer.Panel2.ResumeLayout(); 
1

ho lottato con questo me stesso e ha concluso che l'unica soluzione, oltre sottoclassi a quanto pare (vedi risposta di hjb417), è stato quello di rendere l'altro scheda visibile. Passare all'altra scheda e tornare al precedente immediatamente prima che il modulo sia visibile non funziona. Se non si desidera avere la seconda scheda visibile, ho usato il seguente codice per risolvere il problema:

this.tabControl.SelectedTab = this.tabPageB; 
this.tabPageB.BindingContextChanged += (object sender, EventArgs e) => { 
    this.tabContainerMain.SelectedTab = this.tabPageA; 
}; 

Supponendo tabPageA è la scheda visibile, e tabPageB è l'invisibile che si desidera inizializzare. Passa alla pagina B e torna indietro una volta completata l'associazione dei dati. Questo è invisibile all'utente nel modulo.

Ancora un brutto scherzo, ma almeno questo funziona. Ovviamente, il codice diventa ancora più brutto quando si hanno più schede.

Problemi correlati