EventToCommand - 在处理选择更改时如何防止递归/重入调用
我正在创建一个交互式搜索页面,该页面在用户输入条件时获取数据。长话短说,我有几个组合框,它们的 SelectionChanged
事件由 EventToCommand
处理。
EventToCommand
调用我的 ViewModel
上的一个方法,该方法除其他外,还更改多个组合框的选定项目。当然,这会触发 EventToCommand
并且整个过程会再次发生...一次...一次...
所以我的问题是,有没有办法绑定到 EventToCommand
真的OneWayToSource
以便来自源的更新不会触发事件吗?
I am creating an interactive search page that fetches data as the user inputs criteria. To make a long story short I have several combo boxes that have their SelectionChanged
event handled by EventToCommand
.
EventToCommand
calls a method on my ViewModel
that, among other things, changes the selected item for several combo boxes. Of course that triggers EventToCommand
and the whole process happens again... and again... and again....
So my question is, is there a way to make the binding to EventToCommand
truly OneWayToSource
so that an update from the source does not trigger the event?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
下面的方法 1 显示了一种可能有价值的技术说明,但方法 2 可能最适合大多数应用程序。
方法 1
作为第一种方法,我采用了 jberger 建议的方法。然而,由于我依赖于事件参数中包含的值,并且我希望根据 MVVM 目标和原则保持 View 和 ViewModel 之间的关注点分离,因此我将这个添加的逻辑放置在我的代码隐藏中,以保持依赖关系查看代码。
我使用事件参数的 AddItems 内容的哈希来区分由于另一个 ComboBox 上的属性绑定而导致的“重复”调用与由于用户交互而对事件处理方法的新调用。
对于一次只能选择一个项目的 ComboBox 来说,连接 AddedItems 的内容并不是严格必要的,但它允许在多选控件上使用类似的方法。
方法2
由于我对方法1并不完全满意,所以我一直在思考更好的解决方案。我的见解是,我实际上只想根据用户交互发出一次命令。键盘焦点看起来是一个很好的标志,可以区分用户交互引起的 SelectionChanged 事件和属性绑定引起的 SelectionChanged 事件。
因此,上述测试可能是大多数情况下的最佳解决方案,包括由不涉及任何 GUI 选择器的另一种输入模式启动 SelectionChanged 事件的情况,例如键盘快捷键或内部状态更改。程序 - 或任何可能执行命令的地方,如果您使用多个控件来控制设置,则该命令将导致多个 SelectionChanged 事件触发。实例属性 FrameworkElement.IsKeyboardFocused 属性和静态 Keyboard.Focus(frameworkElementInstance) 方法也可能对不同的控件或方案有用。
有关键盘焦点的更多信息,请访问 msdn 此处。
Method 1 below shows a perhaps valuable illustration of a technique, but most applications will probably be best served by Method 2.
Method 1
As a first approach, I took the approach suggested by jberger. However, since I am relying upon values contained in the event args, and I want to maintain the separation of concerns between my View and ViewModel as per MVVM goals and principles, I placed this added logic in my code-behind to keep the dependency in the View code.
I used a hash of the AddedItems contents of the event args to distinguish "repeat" calls due to property binding on another ComboBox from new calls to the event handling method due to user interaction.
Concatenating the contents of AddedItems is not strictly necessary for a ComboBox where only one item can be selected at a time, but it allows for a similar approach on multi-select controls.
Method 2
Since I was not completely satisfied with Method 1, I kept thinking about a better solution. The insight that came to me was that I really was only looking to issue the command once, based upon a user interaction. What looks like a good flag to distinguish a SelectionChanged event due to a user interaction from those due to a property binding is keyboard focus.
As such the above test may be the best solution for the bulk of cases, including ones where a SelectionChanged event is initiated by another mode of input not involving any of your GUI selectors, such as a keyboard shortcut or an internal change in state of your program - or any place you might execute a Command which would result in multiple SelectionChanged events firing if you used multiple controls to control a setting. The instance property FrameworkElement.IsKeyboardFocused property and the static Keyboard.Focus(frameworkElementInstance) method may also be useful for different controls or scenarios.
More on Keyboard focus can be found on msdn here.