1

I have textbox. Its updatesourcetrigger property is set to lostfocus. I dont want to set it to proportychanged.

Now lets say, my WPF form is already dirty and user is updating the textbox. Now user directly press CTRL + S key(i.e. it invokes SAVE command) when focus is in textbox only.

Now updated textbox value is not reflected in viewmodel when save command is invoked.(i.e. my view and viewmodel data is not synchronized.)

Can I somehow pull data from view to viewmodel before command invokes or can I call textbox lostfocus event before invoking command.

Thanks in advance....

ranjit powar
  • 104
  • 2
  • 2
  • 10

5 Answers5

0

Bind Key/Gesture directly on your TextBox and do lost focus. Then let the gesture traverse up to Window to do the save. :)

dev hedgehog
  • 8,698
  • 3
  • 28
  • 55
0

You need to call UpdateSource on the BindingExpression of the TextBox, but your viewModel does not have access to the TextBox. so you'll need an event in your viewModel to do it.

Write this code in your view:

myViewModel.UpdateTextSource += () =>
{
    BindingExpression be = textBox1.GetBindingExpression(MainWindow.TextProperty);
    be.UpdateSource();
};

And fire this event inside the command.

if(UpdateTextSource != null)
    UpdateTextSource();

If you need to update different textBoxes then you can add a parameter to the event:

if(UpdateTextSource != null)
    UpdateTextSource(TextProperty.Name);

And in the view set the tag of all text boxes which have this feature to the name of the property.

<TextBox Text="{Binding PhoneNO}" Tag="PhoneNO"/>

Then get the parameter to find the text box which has the same tag as the parameter's value.

myViewModel.UpdateTextSource += t =>
{
    var tb = GetTextBoxWithTag(t);//implement this function
    BindingExpression be = tb.GetBindingExpression(MainWindow.TextProperty);
    be.UpdateSource();
};
Bizhan
  • 16,157
  • 9
  • 63
  • 101
0

You can use PreviewKeyDown handler on the relevant System.Windows.IInputElement. In your case, that would be the Wpf control that implements the CTRL+S. In the handler, check for CTRL+S key press, and if so, "pull" your UIData into the viewmodel.

deafjeff
  • 754
  • 7
  • 25
0

Thank you all for your valuable input.

I have resolved the problem using MoveFocus method.

In my view, before executing the command I have invoked below function:

private void MoveFocus()
{
  var focusElement = KeyBoard.FocusElement as UIElement;

  if(focusElement != null)
  {
    focusElement.MoveFocus(FocusNavigationDirection.Next); 
  }
}

So before my command gets executed, textbox will lose the focus and entered textbox value will be reflected in viewmodel.....:):)

ranjit powar
  • 104
  • 2
  • 2
  • 10
0

I answer for similar question in https://stackoverflow.com/a/47309346/4554937. I write command which update binding source for focused keyboard element and execute it before save data.

Piece of my CommitValueCommand

public void Execute(object parameter)
{
    if (Keyboard.FocusedElement is TextBox textBox)
    {
        BindingOperations.GetBindingExpression(textBox, TextBox.TextProperty).UpdateSource();
    }
}
siwydym67
  • 129
  • 4
  • 12