【问题标题】:ComboBox SelectedItem vs SelectedValue组合框 SelectedItem 与 SelectedValue
【发布时间】:2011-02-22 10:22:41
【问题描述】:

以下代码按您的预期工作 - 当用户在下拉列表中选择新项目时,模型上的 MyProperty 会更新。

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

但是,以下内容的工作方式不同,并且在输入焦点移动到表单上的另一个控件之前不会触发模型更新:

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

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

除此之外:出于我的目的,我最终绑定到SelectedItemSelectedValue。通过这种方式,我可以根据 UI 更改(通过SelectedValue 绑定)获得即时模型更新,并根据编程模型更改(通过SelectedItem 绑定)获得 UI 更新。

【问题讨论】:

    标签: c# winforms data-binding combobox


    【解决方案1】:

    ComboBox 控件继承自 ListControl 控件。

    SelectedItem 属性是ComboBox 控件的正确成员。更改时触发的事件是 ComboBox.SelectionChangeCommitted

    ComboBox.SelectionChangeCommitted

    当所选项目发生更改并且该更改显示在 ComboBox 中时发生。

    SelectedValue 属性继承自 ListControl 控件。 因此,此属性将触发 ListControl.SelectedValueChanged 事件。

    ListControl.SelectedValueChanged

    在 SelectedValue 属性更改时发生。

    也就是说,他们不会同样触发INotifyPropertyChanged.PropertyChanged 事件,但无论如何他们都会。唯一的区别在于触发事件。一旦从 ComboBox 的列表部分做出新的选择,SelectedValueChanged 就会被触发,而当项目显示在 ComboBox 的 TextBox 部分中时,SelectedItemChanged 就会被触发。

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

    这有帮助吗?

    编辑#1

    假设 ComboBox 的列表部分代表一个属性(因为我没有编写控件,所以我无法确认),绑定 SelectedItemSelectedValue 会影响控件内的同一集合。然后,当这个属性被改变时,最后也会发生同样的事情。 INotifyPropertryPropertyChanged.PropertyChanged 事件在同一属性上触发。

    【讨论】:

    • 全部订阅时的事件顺序:1个SelectionChangeCommitted,2个SelectedValueChanged,3个SelectedIndexChanged
    • 我在 MSDN 上发现了这一点:SelectionChangeCommitted 事件仅在用户更改组合框选择时引发,您可以为此事件创建一个处理程序,以便在用户更改组合框时为 ComboBox 提供特殊处理列表中的选定项目。但是,根据 ComboBox 的配置方式以及用户更改所选项目的方式,可能不会引发 SelectionChangeCommitted 事件。或者,您可以处理 SelectedIndexChanged,但请注意,无论索引是通过编程方式更改还是由用户更改,都会发生此事件。
    【解决方案2】:

    我怀疑 ComboBox 的 SelectedItem 属性在控件被验证之前不会更改(当控件失去焦点时会发生这种情况),而 SelectedValue 属性会在用户选择项目时更改。

    这是对控件上发生的焦点事件的引用:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validated.aspx

    【讨论】:

    • 比我的更好的答案。同样重要的是要指出,当绑定到 SelectedValue 时,您将无法使用 SelectedItem,因为它还没有更新。如果我没记错的话,你必须使用 SelectedIndex 从列表控件的 Items 集合中检索。
    【解决方案3】:

    根据我的经验,这是 .NET 中列表控件的长期“功能”。就个人而言,我只会绑定到 SelectedValue 属性的更改并编写解决此“功能”所需的任何其他代码(例如具有两个属性,为 SelectedValue 绑定到一个,然后在该属性的集合上,更新自定义代码中 SelectedItem 的值)。

    不管怎样,希望对你有帮助=D

    【讨论】:

    • 我最终设置了两个绑定——一个绑定到 SelectedValue,一个绑定到 SelectedItem,除此之外不需要任何自定义代码。 :)
    【解决方案4】:

    如果你想让 Selected.Value 工作 你必须做以下事情:

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

    重点是Set DataSource!

    【讨论】:

    • 我正在使用 SelectedValue,同时仅设置 DataSource 和 DisplayMember,而不设置 ValueMember。我很惊讶。
    【解决方案5】:

    如果我们想绑定到字典ie

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

    然后 SelectedItem 将不起作用而 SelectedValue 将

    【讨论】:

    • 这是用于 WPF,而不是 winforms
    猜你喜欢
    • 2021-10-15
    • 2012-05-05
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多