Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: Changes to textbox with focus aren't committed until after the Closing event fires

I have a WPF window for editing database information, which is represented using an Entity Framework object. When the user closes the window, I'd like to notice in the Closing event whether the information has changed and show a message box offering to save the changes to the database.

Unfortunately, changes to the currently focused edit aren't assigned to the binding source until the edit loses focus, which happens at some point after the Closing event has been processed.

Ideally, there would be a routine which commits all changes in the view hierarchy that I could call before checking to see if my entity has been modified. I've also looked for information on programmatically clearing the focus in the control with focus, but can't figure out how to do it.

My question is, how is this typically handled?

like image 289
Finley Lee Avatar asked Oct 21 '08 18:10

Finley Lee


3 Answers

In WPF you can change a Binding to update the source on modification, rather than on losing the focus. This is done by setting the UpdateSourceTrigger property to PropertyChanged:

Value="{Binding Path=MyProperty, UpdateSourceTrigger=PropertyChanged}"
like image 132
sourcenouveau Avatar answered Oct 08 '22 19:10

sourcenouveau


This should get you pretty close:



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

}


like image 8
Donnelle Avatar answered Oct 08 '22 19:10

Donnelle


Maybe you need to remove the focus from the current element

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    FocusManager.SetFocusedElement(this, null);
}
like image 6
user3738532 Avatar answered Oct 08 '22 18:10

user3738532