I have a TextBox, when user presses Enter on their keyboard the value in textbox gets "confirmed" and the string is formatted to the correct amount of decimals.
So if the textbox should have 1 decimal and the user writes "30" without any decimals and presses Enter, then the textbox is automatically updated to "30.0".
The problem is that the CaretIndex is placed at positon 0 when this happens. If i press enter with the Caret after 0 like "30|" then it gets reset to "|30.0" instead of "30.0|" how i want it.
I have a command that gets fired when enter is pressed inside the textbox. However, the command is inside the View Model, and i should not be touching View things (the caret) inside View Model. So how should i go on about doing it?
I was thinking of instead of binding to a command in view model i bind to a function in view (code behind) and from that function i raise the command in VM and set caret, like so:
private void EnterPressed()
{
((ParamTextNodeVM)DataContext).EnterCmd.Execute(null);
ValueBox.CaretIndex = ValueBox.Text.Length;
}
However, this does not work:
<TextBox>
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding EnterPressed}"/>
</TextBox.InputBindings>
</TextBox>
How do i bind "Command" to "EnterPressed" that is inside code behind?
Binding to a function in the code behind would work, but would violate the MVVM pattern. A relay command allows you to bind a command in the view to the view model.
/// <summary>
/// A basic command that runs an Action
/// </summary>
public class RelayCommand : ICommand
{
#region Private Members
/// <summary>
/// The action to run
/// </summary>
private Action mAction;
#endregion
#region Public Events
/// <summary>
/// The event thats fired when the <see cref="CanExecute(object)"/> value has changed
/// </summary>
public event EventHandler CanExecuteChanged = (sender, e) => { };
#endregion
#region Constructor
/// <summary>
/// Default constructor
/// </summary>
public RelayCommand(Action action)
{
mAction = action;
}
#endregion
#region Command Methods
/// <summary>
/// A relay command can always execute
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public bool CanExecute(object parameter)
{
return true;
}
/// <summary>
/// Executes the commands Action
/// </summary>
/// <param name="parameter"></param>
public void Execute(object parameter)
{
mAction();
}
#endregion
}
Within the view model itself, you will need to declare the command as a parameter
public ICommand EnterPressedCommand { get; set; }
Finally, within the constructor of the ViewModel, you will need to assign the command to a function
EnterPressedCommand = new RelayCommand(() => EnterPressed());
This should allow the command to be triggered from the view, and execute your EnterPressed method