如何正确处理 ListBox 中的 SelectedValue 变化(WPF、C#)?

How to handle SelectedValue changing in ListBox correctly (WPF, C#)?

我必须处理 SelectedValue 属性 更改以在用户选择 ListBox 中的某些项目时刷新某些相关的 UI 元素。我使用 SelectedValue 是因为我需要知道项目的具体值,而不是 ListBox 中的索引(索引在不同情况下可能不同)或其他东西。我的 ListBox 绑定到 DataTable 并且 SelectedValue 包含 table 中一行的 ID。

问题是,当我尝试在 SelectionChanged 事件处理程序中获取 ListBoxSelectedValue 时,我收到一个 prior 值,不是现在的!所以,在我花了大约一个小时寻找解决这个问题的方法后,我注意到它是比较有名的,但我看到的解决方案似乎不是很清楚。尽管如此,我 "compiled" 对下一个工作代码片段遇到了一些想法:

((DataRowView)this.LISTBOXNAME.SelectedItem)["ID"]

其中 this 是我当前的 window 并且 SelectedItem 可以转换为 DataRowView 因为 ListBox 绑定到 DataTable正如我之前提到的。这行代码给出了所选 ListBoxItem.

的正确值

但无论如何,我还是想知道如何让SelectedValue直接得到正确的值?可能吗?或者,也许我必须使用另一个事件(不是 SelectionChanged)?如果不可能,有人可以向我解释一下来自 Microsoft 的好心人的思维方式以及为什么 属性 有这样的功能吗?

SelectedValueChanged 事件可以很好地获得正确的 SelectedValue 属性,所以我认为问题可能出在列表框的设置方式上。

您说您已将其绑定到 DataTable,因此您 collection 中的项目是 DataRowView object。

如果您将 SelectedValuePath 设置为 "Id",那么 SelectedValue 属性 将尝试将 SelectedValue 设置为 DataRowView.Id ,我认为这不是有效的 属性.

你的两个选择是

  • 构建 collection 的 object 具有适当的属性以用于 SelectedValue

    <ListBox ItemsSource="{Binding MyCollection}"
             SelectedValue="{Binding SelectedId}"
             SelectedValuePath="Id" ... />
    

    其中 MyCollection 是 object 的 collection,每个包含 .Id 属性.

  • 或使用 SelectedItem 而不是 SelectedValue,并像现在一样使用您的 DataRowView object。 SelectedItem 将设置为您 collection 中的所选项目,其类型为 DataRowView,因此您发布的代码就是访问它的方式。

    ((DataRowView)this.LISTBOXNAME.SelectedItem)["ID"]
    

在这两种方法中,第一种方法通常是 WPF 的首选。


编辑: 下面是对 your question in the comments 的回答,因为它太长了,不适合放在评论中。

A ListBox 意味着绑定到 collection 项。当您将 ItemsSource 设置为 DataTable 时,您实际上绑定到 DataRowView object 的 collection。

有 3 种方法可以从这里获取所选项目:SelectedItemSelectedIndexSelectedValue

  • SelectedItem returns你object被选中了。在本例中,即 DataRowView object,这就是为什么您可以将其转换为 DataRowView 的原因。

  • SelectedIndex returns 你在数据源中选择的项目的索引。

  • SelectedValue 仅当您还设置了 SelectedValuePath 属性 时才能使用。 SelectedValuePath 告诉 WPF 每个数据 object 上的哪个 属性 包含项目的 "Value",因此如果您将其设置为类似 "Id" 的内容,它将尝试在每个 object 上找到 .Id 属性。在您的情况下,object DataRowView 上没有包含您的 Id 列数据的有效 属性,因此这不起作用。

希望能回答您的问题:)