ComboBox选定项与选定值的区别

62

以下代码按照您的期望工作 - 当用户在下拉菜单中选择新项时,模型上的MyProperty将被更新。

comboBox1.DataBindings.Add("SelectedValue", myModel, "MyProperty", true,
DataSourceUpdateMode.OnPropertyChanged);

然而,下面的代码不起作用方式相同,只有当输入焦点移动到表单上的另一个控件时才会触发模型更新:

comboBox1.DataBindings.Add("SelectedItem", myModel, "MyProperty", true, 
DataSourceUpdateMode.OnPropertyChanged);

有人知道为什么吗?我甚至不知道从哪里开始调查原因。提供指向正确方向的指针或直接解释都将同样地受到赞赏。

另外:对于我的需求,我最终绑定了SelectedItemSelectedValue两个属性。这样我就可以通过SelectedValue绑定来获得基于UI更改的即时模型更新,并通过SelectedItem绑定进行基于编程模型更改的UI更新。

5个回答

52

ComboBox控件从ListControl控件继承而来。

SelectedItem属性是ComboBox控件的一个重要成员。当更改时触发的事件是ComboBox.SelectionChangeCommitted

ComboBox.SelectionChangeCommitted

当所选项更改且该更改在ComboBox中显示时会发生该事件。

SelectedValue属性是从ListControl控件继承而来的。 因此,这个属性将触发ListControl.SelectedValueChanged事件。

ListControl.SelectedValueChanged

当SelectedValue属性更改时会发生。

话虽如此,它们不会以相同的方式触发INotifyPropertyChangedPropertyChanged事件,但无论如何都会触发。唯一的区别在于触发事件的方式。SelectedValueChanged在从ComboBox的列表部分进行新选择时立即触发,而SelectedItemChanged在项目在ComboBox的文本框部分显示时触发。

简而言之,它们都代表了ComboBox列表部分中的某个内容。因此,在绑定任一属性时,结果都是相同的,因为PropertyChanged事件在任一情况下都会触发。由于它们都代表列表中的一个元素,因此它们可能被视为相同。

这有帮助吗?

编辑 #1

假设ComboBox的列表部分表示属性(我无法确认,因为我没有编写该控件),绑定SelectedItemSelectedValue中的任何一个都会影响控件内的同一集合。然后,当更改此属性时,最终结果相同。在同一属性上触发INotifyPropertryPropertyChanged.PropertyChanged事件。


订阅全部事件时的顺序:
  1. SelectionChangeCommitted,
  2. SelectedValueChanged,
  3. SelectedIndexChanged。
- Moses
我在MSDN上找到了這個:只有當用戶更改組合框選擇時,才會引發SelectionChangeCommitted事件,您可以創建此事件的處理程序,以在用戶更改列表中的所選項目時為ComboBox提供特殊處理。但是,取決於ComboBox的配置方式以及用戶更改所選項目的方式,可能不會引發SelectionChangeCommitted事件。或者,您可以處理SelectedIndexChanged事件,但請注意,無論是通過編程還是通過用戶更改索引,此事件都會發生。 - Moses

9

比我的回答更好。还要指出的是,当绑定到SelectedValue时,您将无法使用SelectedItem,因为它尚未更新。如果我记得正确,您必须通过SelectedIndex从列表控件的Items集合中检索。 - Allen E. Scharfenberg

2

如果您想让Selected.Value起作用,需要按照以下步骤:

1. Set DisplayMember
2. Set ValueMember
3. Set DataSource (not use Items.Add, Items.AddRange, DataBinding etc.)

关键点是设置数据源!

我的代码使用 SelectedValue,只设置了 DataSource 和 DisplayMember,而没有设置 ValueMember。我感到很惊讶。 - Moses

2
这是我多年使用.NET列表控件的一个长期存在的“特性”。个人建议只需将其绑定到SelectedValue属性的更改事件,并编写任何必要的额外代码来解决这个“特性”(例如具有两个属性,绑定一个用于SelectedValue,然后在该属性的设置中,在自定义代码中从SelectedItem更新值)。无论如何,希望这可以帮到你 =D

1
最终我设置了两个绑定——一个绑定到SelectedValue,另一个绑定到SelectedItem,除此之外我不需要任何自定义代码。 :) - Adam Lear

0

如果我们想要绑定到一个字典 ie

  <ComboBox SelectedValue="{Binding Pathology, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                              ItemsSource="{x:Static RnxGlobal:CLocalizedEnums.PathologiesValues}" DisplayMemberPath="Value" SelectedValuePath="Key"
                              Margin="{StaticResource SmallMarginLeftBottom}"/>

如果使用SelectedItem,它将不起作用,而使用SelectedValue则可以。


1
这是针对WPF的,不是WinForms。 - Andy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接