После 2 дней поиска ответа я наткнулся на этот RoutedCommand учебник. Да, вы можете получить доступ к CommandTarget
из Command
, но это должен быть статический RoutedCommand
. Этот подход соответствует потребности, так как SetAmountCommand
используется несколькими MenuItem
.
1010 * XAML *
<Window x:Class="WpfCommandTargetDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCommandTargetDemo">
<Window.CommandBindings>
<CommandBinding CanExecute="SetAmountCommand_CanExecute"
Command="{x:Static local:CustomRoutedCommand.SetAmountCommand}"
Executed="SetAmountCommand_Executed" />
</Window.CommandBindings>
<StackPanel>
<TextBox Text="{Binding TextBoxOne, UpdateSourceTrigger=LostFocus}">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Set to 35"
Command="{x:Static local:CustomRoutedCommand.SetAmountCommand}"
CommandParameter="35"
CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget}" />
<MenuItem Header="Set to 50"
Command="{x:Static local:CustomRoutedCommand.SetAmountCommand}"
CommandParameter="50"
CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget}" />
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</StackPanel>
</Window>
CodeBehind
public partial class MainWindow : Window
{
private readonly MainVm _mainVm;
public MainWindow()
{
InitializeComponent();
_mainVm = new MainVm();
DataContext = _mainVm;
}
void SetAmountCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
void SetAmountCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
object param = e.Parameter; //CommandParameter
TextBox textbox = e.OriginalSource as TextBox; //CommandTarget
if (textbox != null)
{
textbox.Text = param.ToString();
}
}
}
RoutedCommand
должно быть static
, поскольку оно статически связано с элементом XAML.
public static class CustomRoutedCommand
{
public static readonly RoutedCommand SetAmountCommand = new RoutedCommand();
}
Для полноты, у меня не может быть Command
на моей ViewModel. SetAmountCommand
свойство удалено.
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";
}