繁体   English   中英

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

[英]Manipulate order of WPF TextBox LostFocus event and binding

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

每个可观察对象的属性都绑定到Window的适当小部件( TextBox用于数字类型, CheckBox用于bool等)。

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

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

但我的问题是这样的:绑定场上实际上并不更新基本可观察到的物体 ,直到LostFocus运行事件。 实际效果是将TextBox中的TextBox从“A”更改为“B”将使字段中的数据保持为“A”。 将其从“A”更改为“B”到“C”将持续“B”。

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

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

有没有办法让BindingPreviewLostKeyboardFocusLostFocus事件之间运行?

XAML:

<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;
}

ObservableObject类(setter):

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

谢谢!

如果我正确理解您的问题,这可能是由于默认情况下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();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM