I am working on a WPF project with MVVM and I encountered a problem of not picking up the last text change when I click the save button.
My components are setup like this:
- A toolbar view with toolbar VM, which has the save button. button click event is bound to a Icommand.
- A form view with a bunch of text fields, bound to a sepreate VM.
- the toolbar view and form view are in seperate files.
- all my VMs inherits from BindableBase (part of the Prism.MvvM package)
On button click, I will take the values from the form VM and save them... simple and stragight forward. All is well, except that upon editing the last field, clicking the save button does not trigger the lose focus event. Therefore, the property Set event is not triggered. I will have to click away from the fields after editing then click on the button. Here's my code:
public class ViewModel: BindableBase
{
private string _someText;
public string SomeText
{
get { return _someText; }
set { SetProperty(ref _someText, value); }
}
}
in the view XAML:
<TextBox Text="{Binding SomeText}"/>
in the toolbar XAML:
<Button Command="{Binding SaveCommand}" ToolTip="Save">
</Button>
ViewModel for the toolbar:
public class ToolbarViewModel : BindableBase
{
private ICommand _saveCommand;
public ICommand SaveCommand
{
get
{
return _saveCommand ?? (_saveCommand = new BaseCommandHandler(() => {
//Save code
}, () => true));
}
}
}
code for BaseCommandHandler:
public class BaseCommandHandler : ICommand
{
private Action _action;
private Func<bool> _canExecute;
/// <summary>
/// Creates instance of the command handler
/// </summary>
/// <param name="action">Action to be executed by the command</param>
/// <param name="canExecute">A bolean property to containing current permissions to execute the command</param>
public BaseCommandHandler(Action action, Func<bool> canExecute)
{
_action = action;
_canExecute = canExecute;
}
/// <summary>
/// Wires CanExecuteChanged event
/// </summary>
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
/// <summary>
/// Forcess checking if execute is allowed
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public bool CanExecute(object parameter)
{
return _canExecute.Invoke();
}
public void Execute(object parameter)
{
_action();
}
}
Does anyone know a clean way to make sure focus is lost or a way to trigger the set event of the bindable properties
You should use UpdateSourceTrigger=PropertyChanged
<TextBox Text="{Binding TextValue, UpdateSourceTrigger=PropertyChanged}"/>