WPF:取消数据绑定列表框中的用户选择? [英] WPF: Cancel a user selection in a databound ListBox?

查看:15
本文介绍了WPF:取消数据绑定列表框中的用户选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何取消数据绑定 WPF 列表框中的用户选择?源属性设置正确,但 ListBox 选择不同步.

How do I cancel a user selection in a databound WPF ListBox? The source property is set correctly, but the ListBox selection is out of sync.

我有一个 MVVM 应用程序,如果某些验证条件失败,它需要取消 WPF 列表框中的用户选择.验证由列表框中的选择触发,而不是由提交按钮触发.

I have an MVVM app that needs to cancel a user selection in a WPF ListBox if certain validation conditions fail. Validation is triggered by a selection in the ListBox, rather than by a Submit button.

ListBox.SelectedItem 属性绑定到 ViewModel.CurrentDocument 属性.如果验证失败,则视图模型属性的 setter 将退出而不更改该属性.因此,ListBox.SelectedItem 绑定到的属性不会改变.

The ListBox.SelectedItem property is bound to a ViewModel.CurrentDocument property. If validation fails, the setter for the view model property exits without changing the property. So, the property to which ListBox.SelectedItem is bound doesn't get changed.

如果发生这种情况,视图模型属性设置器会在退出之前引发 PropertyChanged 事件,我认为这足以将 ListBox 重置回旧的选择.但这不起作用——ListBox 仍然显示新的用户选择.我需要覆盖该选择并使其与源属性同步.

If that happens, the view model property setter does raise the PropertyChanged event before it exits, which I had assumed would be enough to reset the ListBox back to the old selection. But that's not working--the ListBox still shows the new user selection. I need to override that selection and get it back in sync with the source property.

为了防止不清楚,这里有一个例子:ListBox 有两个项目,Document1 和 Document2;文档 1 被选中.用户选择 Document2,但 Document1 无法验证.ViewModel.CurrentDocument 属性仍设置为 Document1,但 ListBox 显示已选择 Document2.我需要将 ListBox 选择返回给 Document1.

Just in case that's not clear, here is an example: The ListBox has two items, Document1 and Document2; Document1 is selected. The user selects Document2, but Document1 fails to validate. The ViewModel.CurrentDocument property is still set to Document1, but the ListBox shows that Document2 is selected. I need to get the ListBox selection back to Document1.

这是我的列表框绑定:

<ListBox 
    ItemsSource="{Binding Path=SearchResults, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
    SelectedItem="{Binding Path=CurrentDocument, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

我确实尝试使用从 ViewModel(作为事件)到 View(订阅事件)的回调,以强制 SelectedItem 属性回到旧的选择.我通过事件传递旧文档,它是正确的(旧选择),但列表框选择不会变回.

I did try using a callback from the ViewModel (as an event) to the View (which subscribes to the event), to force the SelectedItem property back to the old selection. I pass the old Document with the event, and it is the correct one (the old selection), but the ListBox selection doesn't change back.

那么,如何使 ListBox 选择与其 SelectedItem 属性绑定到的视图模型属性重新同步?感谢您的帮助.

So, how do I get the ListBox selection back in sync with the view model property to which its SelectedItem property is bound? Thanks for your help.

推荐答案

-snip-

好吧忘记我上面写的.

我刚刚做了一个实验,当你在 setter 中做任何更花哨的事情时,确实 SelectedItem 会失去同步.我猜您需要等待 setter 返回,然后异步更改 ViewModel 中的属性.

I just did an experiment, and indeed SelectedItem goes out of sync whenever you do anything more fancy in the setter. I guess you need to wait for the setter to return, and then change the property back in your ViewModel asynchronously.

使用 MVVM Light 助手的快速而肮脏的工作解决方案(在我的简单项目中测试):在您的 setter 中,恢复到 CurrentDocument 的先前值

Quick and dirty working solution (tested in my simple project) using MVVM Light helpers: In your setter, to revert to previous value of CurrentDocument

                var dp = DispatcherHelper.UIDispatcher;
                if (dp != null)
                    dp.BeginInvoke(
                    (new Action(() => {
                        currentDocument = previousDocument;
                        RaisePropertyChanged("CurrentDocument");
                    })), DispatcherPriority.ContextIdle);

它基本上在 UI 线程上排队属性更改,ContextIdle 优先级将确保它等待 UI 处于一致状态.在 WPF 中的事件处理程序中,您似乎无法自由更改依赖项属性.

it basically queues the property change on the UI thread, ContextIdle priority will ensure it will wait for UI to be in consistent state. it Appears you cannot freely change dependency properties while inside event handlers in WPF.

不幸的是,它在你的视图模型和你的视图之间造成了耦合,这是一个丑陋的黑客.

Unfortunately it creates coupling between your view model and your view and it's an ugly hack.

要使 DispatcherHelper.UIDispatcher 工作,您需要先执行 DispatcherHelper.Initialize().

To make DispatcherHelper.UIDispatcher work you need to do DispatcherHelper.Initialize() first.

这篇关于WPF:取消数据绑定列表框中的用户选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆