数据绑定是否对隐形控制起作用?

这是winforms的.net问题,而不是asp.net。

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

任何人都可以告诉我这是否属实? 测试这个并不难,但我想知道一些确认。

谢谢

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

目前我能找到的唯一参考是这个MSDN线程 。

您的问题与TabControl的行为有关。 请参阅Microsoft错误报告 。 我发布了该问题的解决方法,在创建控件或创建句柄时,将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; } } } 

我们遇到了类似的问题。 我们正在尝试写入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.  // Restore settings to how they were, so you don't know we're here. tbxValueCr.Visible = false; tbxValueDb.Visible = false; chSplitContainer.Panel2.ResumeLayout(); 

我自己也在苦苦挣扎,并得出结论,唯一的解决方法,除了明确的子类化(参见hjb417的答案),就是让其他标签可见。 在表单可见之前切换到另一个选项卡并返回上一个选项卡不起作用。 如果您不希望第二个选项卡可见,我使用以下代码作为解决方法:

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

假设tabPageA是可见选项卡, tabPageB是您要初始化的不可见选项。 这将切换到pageB,并在数据绑定完成后切换回来。 这对表单中的用户是不可见的。

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

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

根据答案,我制作了适合我的方法:

  public partial class Form1: Form { private void Form1_Load(object sender, EventArgs e) { ... forceBindTabs(tabControl1); } private void forceBindTabs(TabControl ctl) { ctl.SuspendLayout(); foreach (TabPage tab in ctl.TabPages) tab.Visible = true; ctl.ResumeLayout(); } } 

除了解决问题之外,选项卡在开头加载,并在用户单击它们时显示得更快。