哎呀!如何在初始化时正确更新ComboBox的SelectedValue?

时间:2013-08-20 19:50:48

标签: c# .net winforms combobox

请考虑以下代码。这是我在我创建的用户控件中实现的流程的简化。

//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?!
}

我的问题是,当我将值赋给控件时,ComboBox中的文本显示我的DataSource表中的第一个项目。

但是,如果我在cbo.SelectedValue = value;行放置一个断点,并使用Intellisense滚动查看与我的ComboBox相关联的属性,那么可以在ComboBox上初始化修复此问题的内容。一旦我继续运行代码,我的表单将加载ComboBox上显示的正确值。

发生了什么,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

我已经找到了如何解决你的问题,但解释为什么这样做并不容易。我在这里找到了一些有趣的东西。首先,我想说我已经找到了至少2种方法来按顺序设置。以下是这两种方式的代码:

//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 :(得分:0)

我也遇到了。但是我的组合在一个仍未添加到表单的面板中。现在我终于找到了这种方式:

            //FAILED cboField.SelectedValue = value;
            //FAILED cboField.HandleCreated += ;
            //FAILED cboField.SelectedItem = item;
            //FAILED cboField.SelectedIndex = indexOfItem;
            cboField.BindingContextChanged += (s1, e2) => {
                cboField.SelectedValue = value;
            };   

你不必再尝试所有那些失败的方法。