Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 操纵WPF TextBox LostFocus事件和绑定的顺序_C#_Wpf_Mvvm_Binding - Fatal编程技术网

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

C# 操纵WPF TextBox LostFocus事件和绑定的顺序,c#,wpf,mvvm,binding,C#,Wpf,Mvvm,Binding,我有一个WPF窗口,它表示一个数据编辑器。窗口的DataContext是一个可观察对象(它实现了INotifyPropertyChanged) 每个可观察对象的属性都绑定到窗口中的相应小部件上(对于数字类型,文本框,复选框,bool,等等) 我不想用“确定”和“取消”按钮来保存更改的属性;我希望在小部件失去焦点时,将底层数据持久化到可观察对象 为此,我处理了小部件的PreviewLostKeyboardFocus和LostFocus事件。我的撤销框架需要一个表示当前状态的可观察对象的副本和一个新

我有一个WPF
窗口
,它表示一个数据编辑器。
窗口的
DataContext
是一个可观察对象(它实现了
INotifyPropertyChanged

每个可观察对象的属性都绑定到
窗口中的相应小部件上(对于数字类型,
文本框,
复选框,
bool
,等等)

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

为此,我处理了小部件的
PreviewLostKeyboardFocus
LostFocus
事件。我的撤销框架需要一个表示当前状态的可观察对象的副本和一个新状态的副本。
PreviewLostKeyboardFocus
事件复制对象,而
LostFocus
事件实际执行保存到数据库的操作

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

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

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

PreviewLostKeyboardFocus
LostFocus
事件之间,是否有办法让
绑定运行

XAML:

observeObject
类(setter):


谢谢

如果我正确理解您的问题,这可能是因为默认情况下,
文本框
会在焦点丢失时更新
源代码

解决此问题的一种方法是将
文本框设置为
PropertyChanged

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

我是在做研究的时候发现的。但我的印象是,修改每个人物都会引发事件。写入我的数据库可能会有很大的开销,同时也会使我的撤销堆栈过于细粒度。哦,我以为你在更新数据库时小部件失去了焦点。哦。。。等一下。我明白你的意思。是的,你说得对。让我试试。您可以将UpdateSourceTrigger设置为显式,并更新lost focus事件句柄中的属性。我认为
UpdateSourceTrigger=PropertyChanged
对于我来说已经足够好了。我不喜欢它在每次按键时不断地更新底层对象,但我实在想不出什么理由来避免这种情况。这是用户思考的时间,所以性能真的不应该是一个问题。非常感谢。
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;
}
public class ObservableObject : INotifyPropertyChanged {
    ...
    public Single ObjectProperty {
        get {
            return this._objectProperty;
        }
        set {
            this._objectProperty = value;
            RaisePropertyChanged("ObjectProperty");
        }
    }
}
<TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=PropertyChanged, StringFormat='{}{0:F5}'}" 
 <TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=Explicit, StringFormat='{}{0:F5}'}" 

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