2009-06-03 7 views
6

Dies ist ein. NET-Problem mit winforms, nicht asp.net.Funktioniert die Datenbindung mit der unsichtbaren Steuerung?

Ich habe ein Windows-Formular mit mehreren Registerkarten. Ich setze Datenbindungen aller Kontrollen, wenn das Formular geladen wird. Aber ich habe festgestellt, dass die Datenbindungen von Steuerelementen auf der zweiten Registerkarte nicht funktionieren. Diese Bindungen funktionieren nur, wenn das Formular geladen ist und wenn ich die zweite Registerkarte auswähle. Das bringt mir den Verdacht: Datenbindungen funktionieren nur, wenn gebundene Steuerelemente sichtbar werden.

Jeder kann mir sagen, ob das stimmt oder nicht? Es ist nicht schwer das zu testen, aber ich würde gerne eine Bestätigung wissen.

Danke

Antwort

8

Sie haben Recht. Ein datengebundenes Steuerelement wird erst aktualisiert, wenn das Steuerelement sichtbar gemacht wird.

Die einzige Referenz, die ich für diesen Moment finden kann, ist this MSDN thread.

+0

Wow. Ich denke, ich habe mich immer nur für die Daten über die Datenquelle entschieden - ich hatte wirklich keine Ahnung, dass die Bindungen nur wirklich funktionierten, wenn das Steuerelement sichtbar war. – overslacked

+1

Ich hatte das gleiche Problem, siehe http://stackoverflow.com/questions/9828153 –

+0

Ich persönlich halte es für ein Feature. – nawfal

0

Dies ist nicht etwas, auf das ich direkt gestoßen bin. Möglicherweise tritt jedoch ein Problem mit der BindingContext. Ohne weitere Details ist es schwer zu sagen, aber wenn ich Sie wäre, würde ich einen Haltepunkt setzen und sicherstellen, dass die Steuerelemente alle im selben Kontext gebunden sind.

4

Ihr Problem hat mit dem Verhalten des TabControl zu tun. Siehe Microsoft bug report. Ich habe eine Problemumgehung für dieses Problem veröffentlicht, die das TabControl ableitet und alle Registerkarten 'iniatumiert', wenn das Steuerelement erstellt oder das Handle erstellt wird. Unten ist der Code für die Problemumgehung.

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

Was genau ist da "IntPtr handle = page_.Handle", wenn man bedenkt, dass der Wert nicht verwendet wird? – Michael

+0

Erzwingt die Erstellung des Griffs –

+0

Danke. Ich dachte, es wäre so etwas.Ich habe das ausprobiert, aber es hat nicht funktioniert. Meine Steuerelemente wurden hinzugefügt, während IsHandleCreated und Created immer noch falsch waren. Ich stelle mir vor, dass einige Feinabstimmungen diesen Fall abdecken würden, aber ich habe einen anderen Weg gewählt: Nachdem ich alle Bindungen gemacht habe, finde ich alle gebundenen Steuerelemente und füge den unsichtbaren Steuerelementen einen VisibleChanged-Handler hinzu, der alles Notwendige tut, wenn sie sichtbar werden. – Michael

0

Wir haben ein ähnliches Problem festgestellt. Wir versuchen, in zwei gebundene, unsichtbare Felder zu schreiben, damit wir das Format, das wir in unser Dataset schreiben, ändern können. Dies funktioniert einwandfrei, wenn die Objekte sichtbar sind, funktioniert jedoch nicht mehr, wenn die Eigenschaft visible in false geändert wurde.

um ihn herum zu bekommen, habe ich den folgenden Code:

  // 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

Ich habe mich mit diesem gekämpft und folgerte, dass die einzige Lösung, neben Subklassifizieren offenbar (hjb417 Antwort sehen), war die andere zu machen Registerkarte sichtbar. Das Wechseln zu der anderen Registerkarte und das Zurückgehen zu der vorherigen unmittelbar bevor das Formular sichtbar ist, funktioniert nicht. Wenn Sie nicht über die zweite Registerkarte sichtbar haben wollen, habe ich den folgenden Code als Behelfslösung verwendet:

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

Unter der Annahme, tabPageA sind die sichtbaren Registerkarte und tabPageB ist die unsichtbar Sie wollen initialisieren. Dies wechselt zu Seite B und schaltet zurück, sobald die Datenbindung abgeschlossen ist. Dies ist für den Benutzer im Formular unsichtbar.

Immer noch ein hässlicher Hack, aber zumindest funktioniert das. Natürlich wird er Code noch hässlicher, wenn Sie mehrere Tabs haben.

Verwandte Themen