我注意到当用户激活菜单或工具栏时,与UpdateSourceTrigger==LostFocus
的绑定不会更新。
这导致了一个不幸的情况,当用户从菜单或工具栏中选择“保存文件”时,用户所做的最后一次更改会丢失。
是否可以轻松解决此问题,或者是否必须将所有绑定更改为UpdateSourceTrigger=PropertyChanged
。
答案 0 :(得分:11)
我知道这有点旧,但对于任何未来的读者,只需在ToolBar
上设置以下内容就可以为我工作:
FocusManager.IsFocusScope="False"
答案 1 :(得分:3)
问题是,当菜单项被激活时,TextBox实际上不失去焦点。因此,UpdateSourceTrigger LostFocus
不会触发。根据您的(视图)模型,UpdateSourceTrigger PropertyChanged
可能是也可能不是可行的解决方法。
对我来说,PropertyChanged
不是一个选项(我需要在用户完成输入后验证数据,而不是之间),所以我通过调用此方法使用了一种解决方法在“保存文件”(或任何其他需要最新模型的菜单/工具栏条目)之前:
Public Shared Sub SaveFocusedTextBox()
Dim focusedTextBox = TryCast(Keyboard.FocusedElement, TextBox)
If focusedTextBox IsNot Nothing Then
Dim be = focusedTextBox.GetBindingExpression(TextBox.TextProperty)
If be IsNot Nothing Then be.UpdateSource()
End If
End Sub
在此相关问题中可以找到针对此问题的其他一些方法:
(事实上,这个方法的功劳归功于rudigrobler在这个问题上的答案。)
答案 2 :(得分:3)
这对我很有用:
Private Sub MenuItem_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
Keyboard.FocusedElement.RaiseEvent(New RoutedEventArgs With {.RoutedEvent = LostFocusEvent})
End Sub
答案 3 :(得分:1)
虽然这里有有用的答案,但恕我直言,这并不是最好的方法。对我而言,最佳和次佳的选择是:
TextBox
之前和之后的TextBox
焦点范围内具有可聚焦元素。这是恕我直言的最佳选择,,但是只有在这是合理用户界面选择时,才应使用它。已经有自然会围绕TextBox
的UI元素。LostKeyboardFocus
事件,然后显式更新绑定。请注意,尽管TextBox
的焦点范围并没有失去焦点,但是不会总是丢失 keyboard 焦点。 / li>
第二个选项如下:
<TextBox Text="{Binding SomeProperty}" LostKeyboardFocus="TextBox_LostKeyboardFocus"/>
private void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
BindingOperations.GetBindingExpression((DependencyObject)sender, TextBox.TextProperty)?.UpdateSource();
}
详细说明:
接受的答案将推迟更新绑定的源属性,直到发生某些已知需要该属性值的特定情况(例如执行“保存”命令)。不幸的是,这否定了MVVM范式的一个主要优点,即不必担心何时本身会发生,因为绑定引擎应该负责所有事情。
投票最高的答案对此有所改善,但是正如下面的注释所指出的那样,它仍然是特定于方案的解决方案。需要将其应用于UI中具有自己的焦点范围的每个元素。但更糟糕的是,它实际上修改了元素的UI行为,否则该行为与我们实际上关心的元素完全无关。良好的编码习惯意味着解决原始问题,而不是应用一些不相关的更改,而这些更改恰好具有对我们有利的副作用。
如果您可以简单地在用户界面中排列制表符的顺序,以便在与TextBox
之后紧跟TextBox
的焦点范围内有一个元素,那么恕我直言将是理想的选择解。这意味着用户界面可预测地为用户工作,并且代码与最简单的实现方式保持一致。
但这并不总是可能的。在某些情况下,自然制表符顺序要求TextBox
紧跟Menu
,ToolBar
或其他本身是焦点范围的元素之前或之后。在这种情况下,对我而言,最直接的方法就是通过显式处理LostKeyboardFocus
事件并在该事件发生时更新绑定源来修改绑定的“焦点丢失”行为。