Kamiikoneko
Kamiikoneko

Reputation: 825

WPF textbox that only updates binding when enter is pressed

all. I have a usercontrol "NumericTextBox" that only allows numeric entries. I need to exhibit another specialized behaviour, that is, I need it to be able to bind it to a VM value OneWayToSource and only have the VM value update when I press enter while focusing the textbox. I already have the an EnterPressed event that fires when I press the key, I'm just having a hard time figuring out a way to cause that action to update the binding...

Upvotes: 9

Views: 11253

Answers (3)

Kostja
Kostja

Reputation: 231

Here is a complete version of the idea provided by Anderson Imes:

public static readonly DependencyProperty UpdateSourceOnKeyProperty = 
    DependencyProperty.RegisterAttached("UpdateSourceOnKey", 
    typeof(Key), typeof(TextBox), new FrameworkPropertyMetadata(Key.None));

    public static void SetUpdateSourceOnKey(UIElement element, Key value) {
        element.PreviewKeyUp += TextBoxKeyUp;
        element.SetValue(UpdateSourceOnKeyProperty, value);
    }

    static void TextBoxKeyUp(object sender, KeyEventArgs e) {

        var textBox = sender as TextBox;
        if (textBox == null) return;

        var propertyValue = (Key)textBox.GetValue(UpdateSourceOnKeyProperty);
        if (e.Key != propertyValue) return;

        var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
        if (bindingExpression != null) bindingExpression.UpdateSource();
    }

    public static Key GetUpdateSourceOnKey(UIElement element) {
        return (Key)element.GetValue(UpdateSourceOnKeyProperty);
    }

Upvotes: 9

Anderson Imes
Anderson Imes

Reputation: 25650

If you are using MVVM you can use a combination of decastelijau's approach along with a custom attached property that calls UpdateSource on the textbox when PreviewKeyUp.

public static readonly DependencyProperty UpdateSourceOnKey = DependencyProperty.RegisterAttached(
  "UpdateSourceOnKey",
  typeof(Key),
  typeof(TextBox),
  new FrameworkPropertyMetadata(false)
);
public static void SetUpdateSourceOnKey(UIElement element, Key value)
{

  //TODO: wire up specified key down event handler here
  element.SetValue(UpdateSourceOnKey, value);

}
public static Boolean GetUpdateSourceOnKey(UIElement element)
{
  return (Key)element.GetValue(UpdateSourceOnKey);
}

Then you can do:

<TextBox myprops:UpdaterProps.UpdateSourceOnKey="Enter" ... />

Upvotes: 3

decasteljau
decasteljau

Reputation: 8033

In your binding expression, set the UpdateSourceTrigger to Explicit.

Text="{Binding ..., UpdateSourceTrigger=Explicit}"

Then, when handling the EnterPressed event, call UpdateSource on the binding expression, this will push the value from the textbox to the actual bound property.

BindingExpression exp = textBox.GetBindingExpression(TextBox.TextProperty);
exp.UpdateSource();

Upvotes: 11

Related Questions