C# Windows窗体如何查明selectedindex是由用户更改的还是由代码更改的

C# Windows窗体如何查明selectedindex是由用户更改的还是由代码更改的,c#,.net,winforms,C#,.net,Winforms,我在Windows窗体项目中有一个组合框,其中一个事件附加到selectedindex changed事件。当从代码和用户输入更改selectedindex时,将触发该事件。如何检测所选索引是否因用户输入而更改?事件处理程序仅在用户输入后调用,而不是在代码更改索引后调用。 要么在那里处理这种情况,要么在那里设置一个布尔标志,表示这是用户输入,以便代码的另一部分可以看到上一次索引更改是由于用户输入引起的 我以前遇到过这样的情况:UI更改传播到模型,然后模型更改又传播回UI,这会造成无休止的循环。你

我在Windows窗体项目中有一个组合框,其中一个事件附加到selectedindex changed事件。当从代码和用户输入更改selectedindex时,将触发该事件。如何检测所选索引是否因用户输入而更改?

事件处理程序仅在用户输入后调用,而不是在代码更改索引后调用。
要么在那里处理这种情况,要么在那里设置一个布尔标志,表示这是用户输入,以便代码的另一部分可以看到上一次索引更改是由于用户输入引起的

我以前遇到过这样的情况:UI更改传播到模型,然后模型更改又传播回UI,这会造成无休止的循环。你在处理这样的事情吗

如果是这样,一种解决方法是仅在UI与模型不同时才从模型中更新UI。即:

if (comboBox.SelectedItem != newValue)
    comboBox.SelectedItem = newValue;
如果这不能满足您的需要,另一个选项是临时删除事件处理程序:

comboBox.SelectedIndexChanged -= this.comboBox_SelectedIndexChanged;
comboBox.SelectedIndex = newIndex;
comboBox.SelectedIndexChanged += this.comboBox_SelectedIndexChanged;
或者,指示处理程序忽略此事件:

ignoreComboBoxEvents = true;
comboBox.SelectedIndex = newIndex;
ignoreComboBoxEvents = false;
...
public void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    if (ignoreComboBoxEvents)
        return;
    ...
}
你能用这个事件来代替吗

SelectionChangeCommitted仅在用户更改组合框选择时才会引发

编辑:SelectionChangeCommitted事件有一个重大失败:如果您使用F4下拉列表,然后将鼠标悬停在您的选择上,并使用Tab键转到下一个控件,则不会触发


关于它有一个[closed and deleted]bug,它建议使用
DropDownClosed
事件来捕获此边缘情况。

只要代码更改selectedindex,您就可以设置一个布尔标志,只要设置了该标志,处理程序就可以中止(重置标志)。

您能解释为什么要这样做吗?这似乎是一个相当严重的违反封装的行为,使一个方法根据调用它的内容而不同。我想知道用户何时更改了一个值,而不仅仅是最初设置值的时间。+1我从来不知道这样的事件,很好!我总是使用一个标志来检查它是由用户更改的还是以编程方式更改的。我仍然无法确定
SelectionChangeCommitted
是由上下箭头、空格键还是鼠标单击引起的。我可以处理这些事件并使用
Boolean
标志,但这看起来很混乱。在我的例子中,这似乎是非常有问题的。我将依靠旗帜。谢谢你的信息though@JSON真的没必要感谢我,尤其是在这么长时间之后。但是谢谢你。@stuartd很高兴看到你仍然不时地签入:D+1很好而且灵活的解决方案,带有忽略标志。好的解决方法如果你同时更新了很多值,我喜欢第二种解决方法。似乎工作得很好,而且不需要旗帜!