C# 啊!如何在初始化时正确更新组合框的SelectedValue?
考虑以下代码。这是我在创建的用户控件中实现的流程的简化C# 啊!如何在初始化时正确更新组合框的SelectedValue?,c#,.net,winforms,combobox,C#,.net,Winforms,Combobox,考虑以下代码。这是我在创建的用户控件中实现的流程的简化 //MyUserControl Constructor public MyUserControl(field, value) { InitializeComponents(); string cType = resolveControlType(field); switch (cType) { ... case "ComboBox": AddComboBox(field, v
//MyUserControl Constructor
public MyUserControl(field, value)
{
InitializeComponents();
string cType = resolveControlType(field);
switch (cType)
{
...
case "ComboBox": AddComboBox(field, value);
...
}
}
AddComboBox(string fieldID, object value)
{
ComboBox cbo = new ComboBox();
cbo.DisplayMember = "DisplayMember";
cbo.ValueMember = "ValueMember";
//We set the DataSource to a DataTable
cbo.DataSource = DBCaller.GetListAsDataTable(fieldID);
this.Controls.Add(cbo);
cbo.SelectedValue = value; //<-- Weird stuff happening here?!
// If you don't break here, it
// doesn't look like the correct
// record is selected.
// However, add a breakpoint,
// scroll through cbo's properties
// and this assignment will work
// properly when you continue?!
}
//MyUserControl构造函数
公共MyUserControl(字段,值)
{
初始化组件();
字符串cType=resolveControlType(字段);
开关(cType)
{
...
案例“ComboBox”:AddComboBox(字段、值);
...
}
}
AddComboBox(字符串字段ID,对象值)
{
ComboBox cbo=新ComboBox();
cbo.DisplayMember=“DisplayMember”;
cbo.ValueMember=“ValueMember”;
//我们将数据源设置为DataTable
cbo.DataSource=DBCaller.GetListAsDataTable(fieldID);
this.Controls.Add(cbo);
cbo.SelectedValue=value;//我发现了如何解决您的问题,但解释问题的原因并不容易。我在这里发现了一些有趣的事情。首先,我想说的是,我找到了至少两种方法来安排事情的顺序。下面是这两种方法的代码:
//Solution 1
//Simply you have to add the ComboBox to the parent control first
//before assigning its DataSource
this.Controls.Add(cbo); //<---- This goes first
cbo.DataSource = DBCaller.GetListAsDataTable(fieldID); //<--- This goes after
cbo.SelectedValue = value;
//Solution 2
//This is very strange and interesting, you can also add your ComboBox to
//the parent control after assigning its DataSource (as in your code).
//But you have to ACCESS to the BindingContext property of your ComboBox
//I would like to emphasize the ACCESS, you can perform any kind of access (Read and Write).
//Here are some examples of such access:
cbo.DataSource = DBCaller.GetListAsDataTable(fieldID);
this.Controls.Add(cbo); //<--- like in your code, this is placed here after the DataSource is assigned
//here you can ACCESS the BindingContext
var whatEver = cbo.BindingContext;//READ access
if(cbo.BindingContext == null) Text = "????"; //READ access and of course it's not null
cbo.BindingContext = new BindingContext();//WRITE access
cbo.SelectedValue = value; //<---- This should be placed here after all.
//解决方案1
//只需首先将ComboBox添加到父控件
//在分配其数据源之前
这个.Controls.Add(cbo);//我也遇到了。但是我的组合在一个面板中,仍然没有添加到表单中。现在我终于找到了这种方法:
//FAILED cboField.SelectedValue = value;
//FAILED cboField.HandleCreated += ;
//FAILED cboField.SelectedItem = item;
//FAILED cboField.SelectedIndex = indexOfItem;
cboField.BindingContextChanged += (s1, e2) => {
cboField.SelectedValue = value;
};
您无需再次尝试所有这些失败的方法。当您完成调试且应用程序完全运行时,所选值仍然正确?@YairNevet.正确。如果我在分配行中断,在分配发生之前,使用intellisense滚动查看cbo
的属性,则一切正常。但是,如果我不要调试,我的组合框显示我的数据表中第一条记录的文本。我假设值是正确的,但是控件上显示的文本是不正确的。但是,这种假设只是推测性的,没有经过验证。代码没有显示它,但是您是否添加了SelectedIndexChanged
事件?@YuriyGalanter:是的。实际上SelectedIndexChanged事件是一个lambda语句,就在分配数据源之后。仅供参考,在event语句中,我从不取消该事件。我只是检查是否选择了第一行,这样我就可以提示用户输入一个新的记录输入屏幕——但在初始化时不会发生这种情况。@RLH您可以发布事件的代码吗dler?另外(作为测试),在分配SelectedValue
后,是否可以附加处理程序?我会给出答案,但我在大约10秒钟前刚刚找到了一个解决方案。在我的情况下,在设置数据源之后,我调用了cbo.CreateControl()
。我认为CreateControl方法完成了所有数据、文本和绘图区域的初始化。我假设这通常是在显示(或正在显示)控件后调用的在表单上。@RLH听起来很有趣。你甚至可以注册VisibleChanged
,然后在那里检查设置SelectedValue
,当它确实可见时,你甚至可以尝试设置它。刚刚测试过这种方法,它也可以工作。是的,我曾经考虑过类似的方法,但那感觉更像是“黑客”而不是一个合理的答案。组合框的这种行为一定有原因,我也对这个原因感兴趣。