Force binding to update when Command is triggered

Rather than changing focus you could also just update the binding source if the current element is a TextBox. You could do something similar for other controls but in my experience I've only had this problem with TextBox.

  // if the current focused element is textbox then updates the source.     
    var focusedElement = Keyboard.FocusedElement as FrameworkElement;
    
    if (focusedElement is TextBox)
    {
       var expression = focusedElement.GetBindingExpression(TextBox.TextProperty);
        if (expression != null) expression.UpdateSource();
    }

I have solved this now by explicitely setting the focus to some other element before asking for the values. This obviously makes the element that currently has the focus lose it and update the binding.

To set the focus, I have written an attached property, inspired by answers on other questions. Also, together with my other question I made this somewhat automated.

So to use it, I basically attach my property to an element, in this case a tab control:

<TabControl c:Util.ShouldFocus="{Binding ShouldClearFocus}">

In my view model, I have a simple boolean property ShouldClearFocus that is a standard property raising a PropertyChangedEvent, so data binding works. Then I simply set ShouldClearFocus to true when I want to reset the focus. The attached property automatically sets the focus and resets the property value again. That way I can keep setting ShouldClearFocus without having to set it to false in between.

The attached property is a standard implementation with this as its change handler:

public static void ShouldFocusChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    if (!(bool)e.NewValue || !(obj is FrameworkElement))
        return;

    FrameworkElement element = (FrameworkElement)obj;
    if (element.Focusable)
        element.Focus();

    // reset value
    BindingExpression bindingExpression = BindingOperations.GetBindingExpression(obj, ShouldFocusProperty);
    if (bindingExpression != null)
    {
        PropertyInfo property = bindingExpression.DataItem.GetType().GetProperty(bindingExpression.ParentBinding.Path.Path);
        if (property != null)
            property.SetValue(bindingExpression.DataItem, false, null);
    }
    else
        SetShouldFocus(obj, false);
}

On your TextBox, you need to set the UpdateSourceTrigger on your text binding which defines when the source will be updated with the textbox value. By default it's LostFocus for the Text property, which is exactly what's happening - it only updates the source when it loses focus. You should set the value of UpdateSourceTrigger to PropertyChanged and it will update each time the textbox value changes.

e.g.

<TextBox ... Text="{Binding Foo, UpdateSourceTrigger=PropertyChanged}"/>

Path is the default property when using the Binding command, so the above is equal to Path=Foo


Here is the class I used for a similar situation:

public class TextBoxUpdatesTextBindingOnPropertyChanged : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.TextChanged += TextBox_TextChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        AssociatedObject.TextChanged -= TextBox_TextChanged;
    }

    void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        var bindingExpression = AssociatedObject.GetBindingExpression(TextBox.TextProperty);
        bindingExpression.UpdateSource();
    }
}

XAML:

<TextBox Text="{Binding UserName,Mode=TwoWay,UpdateSourceTrigger=Explicit}">
    <i:Interaction.Behaviors>
        <h:TextBoxUpdatesTextBindingOnPropertyChanged />
    </i:Interaction.Behaviors>
</TextBox>

Calling OnPropertyChanged("YourPropertyName") will alert the view to update the bound value.

Otherwise check out this answer: WPF TextBox DataBind on EnterKey press.