如何正确处理 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
事件处理程序中获取 ListBox
的 SelectedValue
时,我收到一个 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 种方法可以从这里获取所选项目:SelectedItem
、SelectedIndex
和 SelectedValue
。
SelectedItem
returns你object被选中了。在本例中,即 DataRowView
object,这就是为什么您可以将其转换为 DataRowView 的原因。
SelectedIndex
returns 你在数据源中选择的项目的索引。
SelectedValue
仅当您还设置了 SelectedValuePath
属性 时才能使用。 SelectedValuePath
告诉 WPF 每个数据 object 上的哪个 属性 包含项目的 "Value",因此如果您将其设置为类似 "Id"
的内容,它将尝试在每个 object 上找到 .Id
属性。在您的情况下,object DataRowView
上没有包含您的 Id 列数据的有效 属性,因此这不起作用。
希望能回答您的问题:)
我必须处理 SelectedValue
属性 更改以在用户选择 ListBox
中的某些项目时刷新某些相关的 UI 元素。我使用 SelectedValue
是因为我需要知道项目的具体值,而不是 ListBox
中的索引(索引在不同情况下可能不同)或其他东西。我的 ListBox
绑定到 DataTable
并且 SelectedValue
包含 table 中一行的 ID。
问题是,当我尝试在 SelectionChanged
事件处理程序中获取 ListBox
的 SelectedValue
时,我收到一个 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 种方法可以从这里获取所选项目:SelectedItem
、SelectedIndex
和 SelectedValue
。
SelectedItem
returns你object被选中了。在本例中,即DataRowView
object,这就是为什么您可以将其转换为 DataRowView 的原因。SelectedIndex
returns 你在数据源中选择的项目的索引。SelectedValue
仅当您还设置了SelectedValuePath
属性 时才能使用。SelectedValuePath
告诉 WPF 每个数据 object 上的哪个 属性 包含项目的 "Value",因此如果您将其设置为类似"Id"
的内容,它将尝试在每个 object 上找到.Id
属性。在您的情况下,objectDataRowView
上没有包含您的 Id 列数据的有效 属性,因此这不起作用。
希望能回答您的问题:)