My setting is as described below:
The problem is that when I press Enter on the keyboard, the value that I provided in the last input field is not pushed to the underlying property of the ViewModel.
I suspect that this has something to do with the fact that the input field hasn't lost the focus before the window is closed (and thus all the bindings are "dissolved"). For comparison, if I click the "Save" button (instead of letting its Click being handled by the window on Enter), the value is updated in the property. Moreover, if I add (horror! horror!) an event handler to the button's Click event, and call button.Focus() in code-behind, everything works!
What can be the remedy?
I obviously don't want to handle any window closing events, and "manually" fetch the missing values... This would violate the whole MVVM concept :-(
Any better suggestions?
Thank you, Alex
By default, a TextBox
only notifies it's source that its value has changed once it loses focus. You can change that in your binding by setting UpdateSourceTrigger=PropertyChanged
. This will make the TextBox send an update notification to its source its Text gets changed instead of only when it loses focus.
If you don't want to send an update notification anytime a key is pressed, you can create an AttachedProperty
to update the source if the Enter key is pressed.
Here's the AttachedProperty that I use for situations like this:
// When set to True, Enter Key will update Source
#region EnterUpdatesTextSource DependencyProperty
// Property to determine if the Enter key should update the source. Default is False
public static readonly DependencyProperty EnterUpdatesTextSourceProperty =
DependencyProperty.RegisterAttached("EnterUpdatesTextSource", typeof (bool),
typeof (TextBoxHelper),
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 += OnPreviewKeyDownUpdateSourceIfEnter;
}
else
{
sender.PreviewKeyDown -= OnPreviewKeyDownUpdateSourceIfEnter;
}
}
}
// If key being pressed is the Enter key, and EnterUpdatesTextSource is set to true, then update source for Text property
private static void OnPreviewKeyDownUpdateSourceIfEnter(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();
}
}
}
#endregion //EnterUpdatesTextSource DependencyProperty
Try this.
{Binding Property,UpdateSourceTrigger=PropertyChanged,Mode=OneWayToSource}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With