这是winforms的.net问题,而不是asp.net。
我有一个带有多个标签的窗体。我在加载表单时设置所有控件的数据绑定。但我注意到第二个选项卡上的控件的数据绑定不起作用。这些绑定仅在加载表单和选择第二个选项卡时起作用。这给我带来了怀疑:数据绑定仅在绑定控件可见时才起作用。
任何人都可以告诉我这是否属实?测试这个并不难,但我想知道一些确认。
由于
答案 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();
}
}
除了解决问题外,这些选项卡还在开头加载,并且在用户单击它们时显示得更快。