wpf - 撤消日记 : focusing the control being undone

标签 wpf mvvm focus undo

我正在为我的 WPF 数据输入屏幕编写撤消日志,它将跟踪所有控件的更改。当用户选择撤消时,我不仅要恢复最新的更改,还要将焦点放回其值正在恢复的控件中。我正在努力寻找将注意力重新集中的最佳方式。

我的 ViewModel 将是处理撤销日志的部分:ViewModel 的属性 setter 将在更新 DataModel 之前捕获一些“之前”状态。一种或另一种方式,“之前”状态需要包含足够的信息,以便我能够稍后将焦点放回原处。

举例来说,假设有两个数据输入字段:地址和城市。 ViewModel 对每个都有一个属性,View 对每个绑定(bind)到相应 ViewModel 属性的 TextBox 都有一个。

让我们按照用户刚刚在地址字段中键入一个值,然后单击城市字段的示例进行操作。我正在使用默认的 UpdateSourceTrigger.LostFocus 行为,因此本地址文本框失去焦点时,地址更改会被保存。到目前为止,关于如何解决这个问题,我有三种不同的想法,但我对 WPF 的了解不够多,无法知道如何使它们中的任何一个起作用。

  • 我可以忘记 MVVM 样式的数据绑定(bind),并 Hook 编辑控件的 LostFocus 事件(或添加附加行为,或制作包装 TextBox 的自定义控件,或者......)。在 LostFocus 事件处理程序中,我可以创建一个撤消帧,其中包含对事件发送者的引用。后来,在撤消之后,我只关注我保存了其引用的控件。这可能是我在 WinForms 中所做的,但在 WPF 中我宁愿坚持使用 ViewModel 模式——我宁愿让日志逻辑存在于 ViewModel 中而不是 View 中,以确保可测试性。所以这个选项不是我的第一选择。
  • 在我的 ViewModel 的属性 setter 中,我可以捕获正在设置的 ViewModel 属性的名称(本示例中的“地址”),并将该名称存储在撤消框架中。稍后,在撤消时,我可以遍历 View 中的所有控件,寻找我能找到的第一个绑定(bind)到名为 Address 的属性的控件。一旦我找到一个这样的控制,我就会把焦点放在它上面。这足以满足我的需要,因为我不希望将多个控件绑定(bind)到同一个 ViewModel 属性。问题是这需要深入研究绑定(bind)表达式,这是我不知道该怎么做的事情。 (它还会引入更多基于名称的后期绑定(bind),如果我重构可能会中断。)
  • 当我的 ViewModel 将更改添加到撤消堆栈时,它可以要求 View 层(通过接口(interface))创建一个知道哪个控件具有焦点的 Memento。在撤消时,日记会要求 View 恢复该备忘录。这里的问题是,当我的 ViewModel 的属性被设置并添加撤消框架时,键盘焦点已经移动到 City TextBox,因此“创建纪念品”需要比“哪里”更棘手当前的键盘焦点”,我不知道如何完成这个技巧。

  • 任何人对进行上述任何工作有任何建议,或者有可能更好的替代方法?

    最佳答案

    我将从您的第二种方法开始。但是,我不会深入研究绑定(bind)列表,而是将控件的高亮属性硬编码为 VM 属性。

    例如,这是我的虚拟机:

    public class VM
    {
        public double Price { get; set; }
        public bool PriceHighlighted { get; set; }
    }
    

    然后,将 Price 属性绑定(bind)到 TextBox 并将 TextBox 的背景绑定(bind)到 PriceHighlighted(使用值转换器)。现在 VM 可以完全控制 View 的 react 方式。当用户执行“撤消”操作时,VM 可以将所有 xxxHightlighted 设置为 false,除了您要突出显示的那个。

    关于wpf - 撤消日记 : focusing the control being undone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/852531/

    相关文章:

    c# - 从工作线程刷新 DataGrid

    winforms - 是否可以避免 Focus on SplitContainer?

    c# - 在代码隐藏文件中设置报表查看器的 rdlc 文件的相对路径

    c# - 替换 WPF 中的部分默认模板

    c# - 使用 wpf mvvm 在同一 View 上的 View 模型之间切换

    mvvm - 如何使用 PRISM 和 MEF 将 View 注入(inject) UI?

    jquery - 如何关注qtip(jquery插件)中的元素

    qt - 当子小部件具有焦点时,如何更改父小部件的背景?

    wpf - ExceptionValidationRule 不对异常使用react

    wpf - DataGrid:仅在保存第一行的更改后才允许编辑第二行