2009-06-03 37 views
6

这是winforms的.net问题,而不是asp.net。数据绑定是否在隐形控制上工作?

我有一个带有几个选项卡的窗体。当表单被加载时,我设置了所有控件的数据绑定。但我注意到第二个选项卡上控件的数据绑定不起作用。这些绑定仅在表单加载时以及我选择第二个选项卡时起作用。这给我带来了怀疑:数据绑定仅在绑定控件可见时才起作用。

任何人都可以告诉我这是真的还是不是真的?这不难测试,但我想知道一些确认。

谢谢

回答

8

你是对的。数据绑定控件在控件变为可见之前不会更新。

我现在唯一可以找到的参考文献是this MSDN thread

+0

哇。我想我一直都是通过数据源去寻找数据 - 我真的不知道只有在控件可见的时候,绑定才真正起作用。 – overslacked 2009-06-03 07:27:44

+1

我有同样的问题,请参阅http://stackoverflow.com/questions/9828153 – 2012-03-22 19:11:50

0

这不是我直接遇到的。但是,您可能遇到BindingContext的问题。没有更多的细节很难说,但如果我是你,我会设置一个断点并确保所有控件都绑定在同一个上下文中。

4

您的问题与TabControl的行为有关。请参阅Microsoft bug report。我发布了一个针对该问题的解决方法,该方法对控件创建或创建句柄时TabControl进行了子类化,并将所有选项卡页面“Iniatalizes”。以下是解决方法的代码。

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

我们遇到过类似的问题。我们正在尝试写入2个不可见的字段,以便我们可以更改我们写入数据集的格式。这在对象可见时正常工作,但在可见属性更改为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的答案),是使对方标签可见。切换到另一个选项卡并在窗体可见之前立即返回到上一个窗口不起作用。如果你不希望有第二个选项卡中看到,我用下面的代码作为一种解决方法:

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

假设tabPageA是可见的标签,tabPageB是要在一个无形初始化。这将切换到pageB,并在数据绑定完成后切换回来。这在表单中对用户是不可见的。

仍然是一个丑陋的黑客,但至少这个作品。当然,当你有多个标签时,他的代码会变得更加丑陋。