当在一个不可聚焦的控件上进行操作时,如何强制进行绑定更新?

3
我有一个问题,我已经以一种不太优雅的方式解决了它,并且想知道是否有更好的解决方法。
我的View可能具有文本框,只有在失去焦点时才会更新其绑定(它们绑定的属性使用UpdateSourceTrigger=LostFocus)。这几乎是正确的……我可以将绑定的UpdateSourceTrigger设置为PropertyChanged,我就不会有问题,而且一切都会按预期工作……但是,在更新这些绑定属性时可能发生一些计算上昂贵的东西(涉及对编辑对象的深入检查,可能会变长),因此我实际上只想在完成编辑后更新绑定。
这会给工具栏带来问题,因为它们的按钮无法获得焦点,因此单击它们(并发出命令)实际上不会使文本框失去焦点,因此当执行命令时,绑定尚未更新(考虑到实体编辑视图,其中包含一个工具栏“保存”按钮,单击该按钮会调用保存命令,实际上保存实体。在这种情况下,实体将保存为失去焦点之前的文本框值)。
我可以在引发命令之前检查绑定并更新源(这就是我现在正在做的),但是这意味着:
要么:访问命令执行的绑定(或控件)。这被认为是不够优雅的解决方案。命令操作在其他库中定义,应该与WPF无关。
要么:在代码后台事件处理程序上执行命令,并在引发命令之前执行绑定更新(或仅将焦点设置为其他内容并允许WPF更新源)。这就是我现在正在做的事情,也是我不喜欢的事情(如果有其他解决方案,我更喜欢直接将命令分配给工具栏按钮)。
要么:View接口具有“ForceEndEdit()”,View执行它,并在我执行可能会引起此问题的操作时调用它。我觉得这相当奇怪,不想这样做。
是否有方法告诉WPF在用户调用命令或单击控件外的按钮时更新绑定,而不一定失去焦点?如果没有,是否有任何解决此问题的解决方案,比提出的上述解决方案更优雅,并且我可能没有想到?
如我所说,触发绑定更新OnPropertyChanged(这是我看到的类似问题-尽管不完全相同-提出的解决方案)在这种特殊情况下不是足够好的解决方案。
PS:这不仅适用于文本框,而且适用于任何类型的编辑控件(日期选择器,范围选择器等)。这些控件可能是第三方的,我不一定能访问它们的源代码。
PS2:我正在使用.NET 4.5

你使用的是哪个版本的.NET? - toadflakz
4.5,抱歉,将添加到问题中。 - Jcl
1个回答

3
如果在UpdateSourceTrigger=PropertyChanged期间进行计算密集型操作,则应考虑在Binding中使用Delay,以便Binding仅在用户停止在控件中输入值后才更新。这可以解决您的问题,因为它基于交互时间而不是依赖于其他事件/发生之前启动更新。此属性是.NET 4.5中的新属性,这就是我问您使用的.NET版本的原因。

1
在我开始对这个解决方案进行测试之前,我有另一个问题:延迟是否发生在除了属性更改之外的其他操作后立即?我的意思是...如果我设置了500毫秒的延迟,并且“保存”按钮有一个ctrl+s的快捷键。如果我正在编辑文本,在这500毫秒之前按下ctrl+s,绑定会在执行命令之前更新吗?如果不是这样,那么我就处于同样的情况(想法是:在引发命令之前,所有绑定都应该已经更新,无论是什么原因引发了命令) - Jcl
1
在这里,我认为你也需要保持现实。500毫秒等于0.5秒。你认为用户在完成输入后会多快地尝试点击保存按钮或Ctrl+S快捷键呢?我认为即使有500毫秒的延迟,你也不太可能出现脏绑定更新。如果延迟是3000毫秒,那么肯定会出现,但是500毫秒不会。顺便说一下,在我工作的一个实时应用程序中,我们的更新延迟为300毫秒。;-) - toadflakz
2
我通常在打代码的同时按下Visual Studio上的Ctrl+S键,速度相当快。作为一个打字速度较慢的人,如果我不必思考就能打出3-4个字符每秒,这是很容易做到的(而且我按Ctrl-S时绝对不会思考)。无论如何,我会相信你说的300毫秒,并与普通用户进行一些测量,然后稍微减少延迟以确保安全。经过查看代码库,更改所有这些“不正确”的绑定所带来的影响实际上并不大,因此这可能是一个解决方案。 - Jcl
1
我刚刚在实际应用中进行了一些快速测试(而不是样板视图),即使鼠标必须单击功能区,我也能够在不费力的情况下在200毫秒内单击保存按钮。恐怕这个解决方案对我来说行不通,需要进行额外的检查。特别是在这个应用程序中,我不能承受“快速用户”由于此问题而丢失数据。具体而言,在窗口上有一个“保存并关闭”按钮,该按钮不允许用户看到实际数据尚未保存,直到为时已晚(如果只是“保存”,则稍后关闭前会发出警告):-/ - Jcl
1
就像我说的那样,计算时间长得足以使输入不流畅,但又不够长以至于“真正中断”... 当我在编辑时,我可能会让按钮闪烁,这并不是我想要的。有意义的过程是:“在点击保存按钮后完成更新绑定,然后保存”,这就是我现在正在做的... 我希望有一种绑定触发器可以在“主动失去焦点”或“等待一段时间”之外执行,比如:“在点击其他非可聚焦控件时”,但由于没有这样的触发器,我现在使用的事件处理程序,或者一个更好的“可绑定代理命令”都可以。 - Jcl
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接