I have a ContextMenu that suppose to set value on its parent TextBox.
The textbox cannot have a name (by requirement), so I am setting it as CommandTarget
<TextBox Text="{Binding TextBoxOne, UpdateSourceTrigger=LostFocus}">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Set to 35"
Command="{Binding SetAmountCommand}"
CommandParameter="35"
CommandTarget="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}}}" />
<MenuItem Header="Set to 50"
Command="{Binding SetAmountCommand}"
CommandParameter="50"
CommandTarget="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}}}" />
</ContextMenu>
</TextBox.ContextMenu>
How to access the TextBox.Text from inside the Command ?
ViewModel
public class MainVm : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string TextBoxOne { get; set; } = "One";
private ICommand _setAmountCommand;
public ICommand SetAmountCommand
{
get
{
return _setAmountCommand ?? (_setAmountCommand = new CommandParameterHandler((o) =>
{
object param = o;
double amount = (double)o;
//MyParentTextBox.Text = amount; //What to put here ? (Cannot be TextBoxOne = amount, need to route from View)
}, true));
}
}
}
Generic CommandParameterHandler
public class CommandParameterHandler : ICommand
{
private Action<object> _action;
private bool _canExecute;
public CommandParameterHandler(Action<object> action, bool canExecute)
{
_action = action;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
}

CommandTargetproperty is only applicable when theICommandis aRoutedCommand, which is not true in your case.RelativeSourcedoesn't work. See here stackoverflow.com/questions/15550240/…RelativeSourceto something depending onPlacementTarget, like this<MenuItem Command="CMD" CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget}">. This makesCommandTargetvalue be bound to an element the menu is open on. If you needDataContext, just add one more binding.