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

Jam*_*nen 4 c# wpf binding mvvm

我有一个Window代表数据编辑器的WPF .所述DataContextWindow是可观察到的对象的(实现INotifyPropertyChanged).

可观察到的对象的属性中的每一个结合到一个适当的插件在Window(TextBox用于数字类型,CheckBoxbool等).

我不想让"确定"和"取消"按钮来保持更改的属性; 我希望当窗口小部件失去焦点时,底层数据将持久保存到可观察对象.

为此,我已经处理了小部件的事件PreviewLostKeyboardFocusLostFocus事件.我的undo框架需要一个代表当前状态的observable对象的副本,以及一个新状态的副本.该PreviewLostKeyboardFocus事件使对象的副本,以及LostFocus活动实际执行保存到数据库中.

但我的问题是这样的:绑定场上不会实际更新底层观察的对象,直到LostFocus运行事件.实际效果是将文本TextBox从"A"更改为"B"将使字段中的数据保持为"A".将其从"A"更改为"B"到"C"将持续"B".

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

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

有没有什么办法让Binding运行之间PreviewLostKeyboardFocusLostFocus事件?

XAML:

<TextBox Text="{Binding ObjectProperty, StringFormat='{}{0:F5}'}" LostFocus="PersistentTextBox_LostFocus" PreviewLostKeyboardFocus="PersistentTextBox_PreviewLostKeyboardFocus" />
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

ObservableObject class(s​​etter):

public class ObservableObject : INotifyPropertyChanged {
    ...
    public Single ObjectProperty {
        get {
            return this._objectProperty;
        }
        set {
            this._objectProperty = value;
            RaisePropertyChanged("ObjectProperty");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

sa_*_*213 5

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

解决这个问题的一种方法是设置TextBox UpdateSourceTriggerPropertyChanged

<TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=PropertyChanged, StringFormat='{}{0:F5}'}" 
Run Code Online (Sandbox Code Playgroud)

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

或者您可以在LostFocus处理程序中设置UpdateSourceTriggerto Explicit并更新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();
    }
Run Code Online (Sandbox Code Playgroud)

  • 您可以将UpdateSourceTrigger设置为Explicit并更新丢失焦点事件处理程序中的属性 (2认同)