2

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

//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 上显示的正确值。

发生了什么事,我该如何解决?

4

2 回答 2

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.

我发现第二个解决方案很奇怪,不容易解释,虽然第一个解决方案可以理解(至少当时我还没有找到第二个解决方案)。

于 2013-08-20T20:45:07.220 回答
0

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

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

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

于 2013-12-23T08:30:44.680 回答