4

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

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

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

为此,我处理了小部件的PreviewLostKeyboardFocusLostFocus事件。我的撤消框架需要代表当前状态的可观察对象的副本和新状态的副本。该PreviewLostKeyboardFocus事件制作对象的副本,并且该LostFocus事件实际执行保存到数据库。

但我的问题是:在事件运行之后,字段上的绑定实际上并没有更新底层的可观察对象。LostFocus最终效果是将 a 中的文本TextBox从“A”更改为“B”会将字段中的数据保留为“A”。将其从“A”更改为“B”到“C”将保持“B”。

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

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

有什么方法可以在和事件之间Binding运行?PreviewLostKeyboardFocusLostFocus

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类(二传手):

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

谢谢!

4

1 回答 1

5

如果我正确理解您的问题,这可能是由于默认情况下TextBox更新Source焦点丢失时的事实。

解决此问题的一种方法是TextBox UpdateSourceTriggerPropertyChanged

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

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

或者您可以在 LostFocus 处理程序中设置并更新 Source UpdateSourceTriggerExplicit

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

    private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
       (sender as TextBox).GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }
于 2013-02-14T21:50:46.350 回答