2009-06-03 7 views
6

これは、asp.netではなくwinformsでの.netの問題です。データバインディングは不可視コントロールで機能しますか?

私はいくつかのタブを持つウィンドウフォームを持っています。私はフォームがロードされるときにすべてのコントロールのデータバインディングを設定します。しかし、私は、2番目のタブのコントロールのデータバインディングが機能しないことに気付きました。これらのバインディングは、フォームがロードされ、2番目のタブを選択したときにのみ機能します。これは私に疑念をもたらします。データバインディングは、バインドされたコントロールが表示されるときにのみ機能します。

これが本当かどうかは誰にでも分かりますか?これをテストするのは難しいことではありませんが、私はいくつかの確認を知りたいと思います。

ありがとうございました

答えて

8

あなたは正しいですか?データバインドされたコントロールは、コントロールが可視になるまで更新されません。

現時点で私が見つけることができる参考資料はthis MSDN threadです。

+0

ワウ。私はデータソースを介して常にデータに行ってきたと思います。コントロールが見えるときにバインディングが実際にしか機能していないことは本当に分かりませんでした。 – overslacked

+1

私は同じ問題を抱えていました。http://stackoverflow.com/questions/9828153 –

+0

個人的に私はそれを機能と考えています。 – nawfal

0

これは私が直接遭遇したことではありません。ただし、BindingContextの問題が発生している可能性があります。詳細がなければ、言いにくいですが、私があなただったらブレークポイントを設定し、コントロールがすべて同じコンテキストでバインドされていることを確認します。

4

問題は、TabControlの動作と関係があります。 Microsoft bug reportを参照してください。コントロールを作成するかハンドルが作成されたときにTabControlをサブクラス化し、すべてのタブページを 'Iniatalize'する問題の回避策を投稿しました。以下は回避策のコードです。

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

値が使用されていないことを考慮して、正確に "IntPtr handle = page_.Handle"は何をしていますか? – Michael

+0

ハンドルを強制的に作成します –

+0

ありがとうございます。私はそれがそれのようなものだと思った。私はこれを試しました、しかし、それは私にとってはうまくいかなかったのです。 IsHandleCreatedとCreatedがまだ間違っている間、私のコントロールが追加されていました。すべてのバインドを行った後、すべてのバインドされたコントロールを見つけ、VisibleChangedハンドラを不可視のハンドラに追加します。これは可視になると必要な処理を行います。 – Michael

0

同様の問題が発生しました。 2つのバインドされた目に見えないフィールドに書き込んで、データセットに書き込む形式を変更できるようにしています。これは、オブジェクトが表示されているときに正常に動作しますが、visibleプロパティがfalseに変更されたときに動作を停止します。私はこれで苦労してきた自分自身を

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

とサブクラス化のほかに唯一の回避策は、明らかに(hjb417の答えを参照)と結論付け、他のを作ることだった。

がラウンドを取得するために、私は次のコードを追加しましたタブが表示されます。フォームが表示される直前にもう一方のタブに切り替えて前のページに戻っても機能しません。あなたが目に見える2番目のタブを持ってしたくない場合は、私は回避策として、次のコードを使用しました:

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

はtabPageAが表示タブで、tabPageBは、あなたがしたい目に見えないものですと仮定すると、初期化する。これはpageBに切り替わり、データバインディングが完了するとスイッチバックします。これは、フォームのユーザーには見えません。

まだ醜いハックですが、少なくともこれは機能します。もちろん、複数のタブがある場合、コードはさらに醜いものになります。

関連する問題