操纵WPF TextBox LostFocus事件和绑定的顺序

时间:2013-02-14 18:41:12

标签: c# wpf mvvm binding

我有一个代表数据编辑器的WPF WindowDataContext的{​​{1}}是一个可观察对象(实现Window)。

每个可观察对象的属性都绑定到INotifyPropertyChanged中的相应窗口小部件(数字类型为WindowTextBoxCheckBox等)。

我不希望使用“确定”和“取消”按钮来保留更改的属性;我希望当小部件失去焦点时,底层数据会持久保存到可观察对象。

为此,我处理了小部件的boolPreviewLostKeyboardFocus事件。我的undo框架需要一个代表当前状态的observable对象的副本,以及一个新状态的副本。 LostFocus事件生成对象的副本,PreviewLostKeyboardFocus事件实际执行保存到数据库。

但我的问题是:在运行LostFocus事件 之后,字段上的绑定实际上并不会更新基础可观察对象。实际效果是将LostFocus中的文本从“A”更改为“B”将使字段中的数据保持为“A”。将其从“A”更改为“B”再变为“C”将持续存在“B”。

我在事件处理程序和底层对象的setter中放置了断点。果然,TextBox首先运行,然后运行PreviewLostKeyboardFocus,最后运行可观察对象的设置器。

我想让它尽可能通用,所以虽然我可以告诉可观察对象使用LostFocus更新自己的属性,但我需要为每个字段分别设置事件处理程序,并且可能会有相当的一些。

有没有办法让KeyboardFocusChangedEventArgsBindingPreviewLostKeyboardFocus事件之间运行

XAML:

LostFocus

代码背后的事件处理程序:

<TextBox Text="{Binding ObjectProperty, StringFormat='{}{0:F5}'}" LostFocus="PersistentTextBox_LostFocus" PreviewLostKeyboardFocus="PersistentTextBox_PreviewLostKeyboardFocus" />

private void PersistentTextBox_LostFocus(object sender, RoutedEventArgs e) { this.ObservableObject.PersistChanges(this.tempObservableObject); } private void PersistentTextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { this.tempObservableObject = this.ObservableObject; } class(s​​etter):

ObservableObject

谢谢!

1 个答案:

答案 0 :(得分:5)

如果我正确理解您的问题,可能是因为默认情况下TextBox会在焦点丢失时更新Source

解决此问题的一种方法是将TextBox UpdateSourceTrigger设置为PropertyChanged

<TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=PropertyChanged, StringFormat='{}{0:F5}'}" 

这将允许在TextBox中进行更改后立即更新基础可观察对象,然后您可以在窗口小部件丢失焦点事件中保留更改

或者您可以将UpdateSourceTrigger设置为Explicit并更新LostFocus处理程序中的Source。

 <TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=Explicit, StringFormat='{}{0:F5}'}" 

    private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
       (sender as TextBox).GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }