Not really sure how to tackle this issue:

I have a "Save" button that has access keys attached to it... but, if I type something into a textbox and press the access keys to save, the textbox doesn't update my viewmodel because it never lost focus. Any way to solve this outside of changing the UpdateSourceTrigger to PropertyChanged?

1

There are 1 answers

1
Rachel On

Your problem is the UpdateSourceTrigger="LostFocus"

This is default for TextBoxes, and means that the TextBox will only update its bound value when it loses focus

One way to force it to update without setting UpdateSourceTrigger="PropertyChanged" is to hook into the KeyPress event and if the key combination is something that would trigger a save, call UpdateSource() first

Here's an Attached Property I like using when the Enter key should update the source.

It is used like this:

<TextBox Text="{Binding Name}" 
         local:TextBoxProperties.EnterUpdatesTextSource="True" />

and the Attached Property definition looks like this:

public class TextBoxProperties
{
    public static readonly DependencyProperty EnterUpdatesTextSourceProperty =
        DependencyProperty.RegisterAttached("EnterUpdatesTextSource", typeof(bool), typeof(TextBoxProperties), 
            new PropertyMetadata(false, EnterUpdatesTextSourcePropertyChanged));

    // Get
    public static bool GetEnterUpdatesTextSource(DependencyObject obj)
    {
        return (bool)obj.GetValue(EnterUpdatesTextSourceProperty);
    }

    // Set
    public static void SetEnterUpdatesTextSource(DependencyObject obj, bool value)
    {
        obj.SetValue(EnterUpdatesTextSourceProperty, value);
    }

    // Changed Event - Attach PreviewKeyDown handler
    private static void EnterUpdatesTextSourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var sender = obj as UIElement;
        if (obj != null)
        {
            if ((bool)e.NewValue)
            {
                sender.PreviewKeyDown += OnPreviewKeyDown_UpdateSourceIfEnter;
            }
            else
            {
                sender.PreviewKeyDown -= OnPreviewKeyDown_UpdateSourceIfEnter;
            }
        }
    }

    // If key being pressed is the Enter key, and EnterUpdatesTextSource is set to true, then update source for Text property
    private static void OnPreviewKeyDown_UpdateSourceIfEnter(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            if (GetEnterUpdatesTextSource((DependencyObject)sender))
            {
                var obj = sender as UIElement;
                BindingExpression textBinding = BindingOperations.GetBindingExpression(
                    obj, TextBox.TextProperty);

                if (textBinding != null)
                    textBinding.UpdateSource();
            }
        }
    }
}