【问题标题】:Argh! How do you correctly update the SelectedValue of a ComboBox on initialization?啊!如何在初始化时正确更新 ComboBox 的 SelectedValue?
【发布时间】:2013-08-20 19:50:47
【问题描述】:

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

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

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

【问题讨论】:

  • 当您完成调试并且您的应用程序完全运行时,选择的值仍然正确吗?
  • @YairNevet。正确的。如果我在分配行中断,在分配发生之前,并使用智能感知滚动浏览cbo 的属性,一切正常。但是,如果我不调试,我的 Combo 会在我的 DataTable 中显示第一条记录的文本。我假设该值是正确的,但是控件上显示的文本不正确。然而,这种假设只是推测性的,并未得到证实。
  • 代码没有显示,但你是在添加SelectedIndexChanged事件吗?
  • @YuriyGalanter:是的。实际上,SelectedIndexChanged 事件是一个 lambda 语句,就在分配 DataSource 之后。仅供参考,在活动声明中,我从不取消活动。我只是检查是否选择了第一行,因此我可以提示用户输入新的记录输入屏幕——不过,这在初始化时不会发生。
  • @RLH 你能发布事件处理程序的代码吗?另外(作为测试)您可以在分配 SelectedValue 后附加处理程序

标签: c# .net winforms combobox


【解决方案1】:

我已经找到了解决问题的方法,但要解释为什么会这样并不容易。我在这里发现了一些有趣的东西。首先,我想说我已经找到了至少 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.

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

【讨论】:

  • 我会给你答案标记,但我大约 10 秒前才找到解决方案。就我而言,在我设置数据源之后,我调用了cbo.CreateControl()。我认为 CreateControl 方法完成了所有数据、文本和绘图区域的初始化。我假设这通常是在表单上显示(或显示)控件之后调用的。
  • @RLH 听起来很有趣。您甚至可以尝试通过注册VisibleChanged 来设置SelectedValue,当它肯定是Visible 并在那里检查。刚刚测试了这种方法,它也有效。
  • 是的,我曾考虑过类似的事情,但感觉更像是“黑客”而不是合法的答案。 ComboBox 出现这种行为肯定是有原因的,我也对这个原因感兴趣。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2012-01-07
    • 1970-01-01
    • 2022-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2021-09-07
    相关资源
    最近更新 更多