请考虑以下示例。请注意,在实词中,绑定源可能是数据对象。为简单起见,我使用的是TextBlock
。
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel Margin="20">
<Label>Enter a Name:</Label>
<TextBox x:Name="txt_Name" Text="{Binding ElementName=display_name, Path=Text, UpdateSourceTrigger=LostFocus}" />
<Label>The name you entered:</Label>
<TextBlock x:Name="display_name" />
<Button x:Name="btn_Save" Click="SaveClick">_Save</Button>
</StackPanel>
</Window>
Class Window1
Private Sub SaveClick(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
MessageBox.Show("Saving your name as: " & display_name.Text)
End Sub
End Class
在上面的示例中,如果我在"Joe"
中输入名称TextBox
并点击“保存”按钮,TextBlock
会根据LostFocus
和数据进行更新正确地“保存”。一切都很好。
但是,如果我然后在"Bob"
中输入TextBox
并使用我的访问密钥(Alt-S)进行保存,则TextBlock
不会更新,因为LostFocus
TextBox
上的事件未被触发。因此,我的绑定源未更新,并且保存了错误的值(即"Joe"
)。
在大多数WPF TextBox
数据输入字段中,您需要在LostFocus
(而不是PropertyChanged
)上进行验证;但是,如果在使用访问密钥时LostFocus
事件未触发(因此绑定未更新),我们如何验证条目?在WinForms中,我们有Validating
和Validated
个事件,但它们在WPF中不存在。
答案 0 :(得分:2)
您可以在保存之前手动执行此操作:
txt_Name.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
有点难看,但它确实有效。
答案 1 :(得分:1)
您还可以在读取值之前更改点击处理程序中的焦点,例如将焦点强制设置为按钮或另一个文本框
这是另一个“丑陋,但它有效”的解决方案,如果您有很多控件或者不想弄乱它们的绑定表达式,这可能是合适的。
答案 2 :(得分:1)
好吧,如果你对现实场景的兴趣比你在这里设计的例子更感兴趣,你可以在文本框上设置绑定来更新数据更改而不是丢失焦点,并且数据将保存在两个场景中没有任何丑陋的黑客。唯一的问题(在Bindings的WPF文档中提到)是这可能会影响应用程序的性能。如果您在任何类型的甚至是相对较新的机器上运行,您将不会注意到差异(我没有)。