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

时间:2009-06-03 07:17:49

标签: c# .net winforms

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

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

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

由于

6 个答案:

答案 0 :(得分:9)

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

目前我能找到的唯一参考是this MSDN thread

答案 1 :(得分: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;
        }
    }
} 

答案 2 :(得分:1)

我们遇到过类似的问题。我们试图写入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();

答案 3 :(得分:1)

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

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

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

根据答案,我制定了适用于我的方法:

 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();
    }
 }

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