0

ComboBox在我的 WinForms 应用程序中有一个DropDown样式,或者换句话说,它允许用户键入一个值,或者从下拉列表中选择它。它看起来像这样:

在此处输入图像描述

我的目标是根据其索引从下拉列表中选择一个项目。所以我这样做:

//I know for sure that i >= 0 && i < comboBox.Items.Count
comboBox.SelectedIndex = i;  //i = index of the existing item

这工作得很好,除非在上面的行之后的一段时间我显示一条消息:

MessageBox.Show("Error");

在这种情况下,在我在这台计算机上进行测试期间,大约 80% 的时间都选择了组合框中的项目。所以这里显然存在一些时间问题。

我需要知道的是选择 ComboBox 项目的“确定”方式是什么?(我的意思是,确保在执行它之后的下一行代码时选择它,或者执行它synchronously。)

PS。我知道我可以简单地将文本分配给它的Text属性,但这不是我想要的。您在我的 ComboBox 实现中看到,我可以为每个项目分配自定义对象,另外我依赖于许多基于选择的事件,例如SelectedIndexChanged.

PS2。我不确定这是否只影响具有该DropDown样式的组合框,还是所有这些组合框。

4

3 回答 3

1

我敢打赌,在您打开MessageBox.

尝试添加这个:

Application.DoEvents();

...在您打电话之前MessageBox.Show();,看看是否有帮助。如果是这样,您可以尝试通过以下方式使控件同步重绘自身

comboBox.Refresh();

comboBox.Invoke如果你正在穿线,你可以试试。此外,PerformLayoutForm/Control上有时会迫使这类事情立即发生,而不是等待绘画消息。

AMessageBox.Show在其轨道中停止所有表单处理。当您确定组合框已经完成了它需要做的所有事情时,最终的解决方案可能是把它放在一个不同的地方。

于 2013-11-07T03:30:24.127 回答
1

好吧,SelectedValueSelectedItem您将对象作为ComboBox.

看看这篇文章:了解 SelectedValue、SelectedValuePath、SelectedItem 和 DisplayMemberPath。你也有可以运行的代码示例。

来自文章:

SelectedItem:这将返回 list/combobox/container 中当前选定的项目。如您所见,这是一个对象(因为我的列表包含对象)。如果您的 List/Combobox/etc 包含字符串列表,它将是一个字符串。如果它包含整数,它将是一个整数。

SelectedValuePath:设置此项将使属性 SelectedValue 返回您在此处选择的属性的值。在我们的示例中,选择“ShapeColor”将使 SelectedValue 仅返回颜色,而不是整个形状对象。

SelectedValue:如果您只想要对象的一部分,请设置上述属性,您将在此处获取该属性的值。请注意,如果不使用 SelectedValuePath,这与使用 SelectedItem 相同。

DisplayMemberPath:将其设置为对象的属性,将导致 GUI 在选择类时显示该属性,而不是查看类名称或您的 Class ToString() 方法(应始终提供。请参阅此处的第 5 项书的目录)。

免责声明:我是文章的作者...

于 2013-11-07T00:20:48.003 回答
1

您的消息框会中断ComboBox处理以更新所选索引。此行为是间歇性的,因为窗体和控件(如 aComboBox和消息框)依赖于 Windows 消息传递系统。在您的选择更改和消息框的同时,表单的其他部分可能会生成数百条消息(有时更多,有时更少)。当消息量很大时,系统可能无法处理一些消息,因此所选索引不会更改。

避免此问题的两种选择:

  • 在对显示消息框的新索引进行健全性检查SelectedIndex 设置。i
  • 使用(下面的示例)异步进行完整性检查BeginInvoke,即。系统完成对更改的选定索引的消息处理之后。

一种使用方式BeginInvoke:

comboBox.SelectedIndex = i;

// Sanity check new index i after message processing for the combo box.
comboBox.BeginInvoke(delegate()
{
    if (/* sanity check fails */)
    {
        MessageBox("Error");
    }   
});

编辑:正如另一个答案所暗示的那样,您可能会通过使用来获得您想要的行为Application.DoEvents,但我会避开这种方法。

于 2013-11-07T08:27:54.667 回答