WPF:对带有焦点的文本框所做的更改不是';直到关闭事件触发后才提交

WPF:对带有焦点的文本框所做的更改不是';直到关闭事件触发后才提交,wpf,data-binding,Wpf,Data Binding,我有一个用于编辑数据库信息的WPF窗口,它使用实体框架对象表示。当用户关闭窗口时,我希望在关闭事件中注意信息是否已更改,并显示一个消息框,用于保存对数据库的更改 不幸的是,在编辑失去焦点之前,对当前焦点编辑的更改不会分配给绑定源,这在关闭事件处理后的某个时间点发生 理想情况下,会有一个例程提交视图层次结构中的所有更改,我可以在检查实体是否已修改之前调用该例程。我还查找了有关使用焦点以编程方式清除控件中焦点的信息,但不知道如何执行 我的问题是,这通常是如何处理的?这应该会让您非常接近: pri

我有一个用于编辑数据库信息的WPF窗口,它使用实体框架对象表示。当用户关闭窗口时,我希望在关闭事件中注意信息是否已更改,并显示一个消息框,用于保存对数据库的更改

不幸的是,在编辑失去焦点之前,对当前焦点编辑的更改不会分配给绑定源,这在关闭事件处理后的某个时间点发生

理想情况下,会有一个例程提交视图层次结构中的所有更改,我可以在检查实体是否已修改之前调用该例程。我还查找了有关使用焦点以编程方式清除控件中焦点的信息,但不知道如何执行


我的问题是,这通常是如何处理的?

这应该会让您非常接近:



private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    ForceDataValidation();
}


private static void ForceDataValidation()
{
    TextBox textBox = Keyboard.FocusedElement as TextBox;

    if (textBox != null)
    {
        BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty);
        if (be != null && !textBox.IsReadOnly && textBox.IsEnabled)
        {
            be.UpdateSource();
        }
    }

}



另外,看看post中的建议,最简单的方法是把焦点放在某个地方。 您可以立即将焦点设置回原位,但在任何位置设置焦点都将触发任何类型控件上的LostFocus事件,并使其更新其内容:

IInputElement x = System.Windows.Input.Keyboard.FocusedElement;
DummyField.Focus();
x.Focus();
另一种方法是获取聚焦元素,从聚焦元素获取绑定元素,并手动触发更新。TextBox和ComboBox示例(您需要添加任何需要支持的控件类型):


假设选项卡序列中有多个控件,下面的解决方案看起来是完整的和通用的(只需剪切和粘贴)


在WPF中,您可以更改
绑定
以在修改时更新源代码,而不是在失去焦点时更新源代码。通过将属性设置为:


可能需要从当前元素中删除焦点

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    FocusManager.SetFocusedElement(this, null);
}

双重问题:解决这个问题的另一种方法:最好的答案,因为它是纯MVVM,并且不涉及对事件的干扰。尽管如此,令人不满意的是,这不是默认触发器,因为它对我来说似乎是最直观的双向绑定行为……我还检查了textbox是否有编辑:
if((textbox!=null)&&(textbox.CanUndo)){…}
Control currentControl = System.Windows.Input.Keyboard.FocusedElement as Control;

if (currentControl != null)
{
    // Force focus away from the current control to update its binding source.
    currentControl.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    currentControl.Focus();
}
Value="{Binding Path=MyProperty, UpdateSourceTrigger=PropertyChanged}"
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    FocusManager.SetFocusedElement(this, null);
}