MouseBinding
не поддерживает действия мыши, только действия мыши, поэтому вы просто не можете делать то, что хотите, используя MouseBinding
. Самая простая альтернатива - это обработчик события code-behind для события MouseRightButtonUp
в том же элементе, к которому вы добавили бы MouseBinding
в качестве InputBinding
. Но я подозреваю, что вы избегаете подхода обработчика событий по своим собственным причинам, но вам следует уточнить, так ли это.
Остальная опция, доступная для использования - это некоторая форма прикрепленного поведения. Есть много способов сделать это, но я буду использовать довольно стандартный System.Windows.Interactivity
из поведения Blend. Все, что вам нужно сделать, это присоединить триггер события для правой кнопки мыши вверх и вызвать команду закрытия. Все, что вам нужно сделать, это в SDK, но, к сожалению, функция вызова команды с именем InvokeCommandAction
не поддерживает должным образом маршрутизируемые команды, поэтому я написал альтернативу под названием ExecuteCommand
.
Вот примерная разметка:
<Grid Background="White">
<Grid.CommandBindings>
<CommandBinding Command="Close" Executed="CommandBinding_Executed"/>
</Grid.CommandBindings>
<!--<Grid.InputBindings>
<MouseBinding Command="Close" MouseAction="RightClick"/>
</Grid.InputBindings>-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseRightButtonUp">
<utils:ExecuteCommand Command="Close"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<StackPanel>
<TextBox Text="Some Text"/>
</StackPanel>
</Grid>
Ваш старый метод закомментирован, а новый метод находится под ним.
Вот код для подключения перенаправленной команды:
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
Close();
}
Наконец, вот реализация ExecuteCommand
:
public class ExecuteCommand : TriggerAction<DependencyObject>
{
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(ExecuteCommand), null);
public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(ExecuteCommand), null);
public UIElement CommandTarget
{
get { return (UIElement)GetValue(CommandTargetProperty); }
set { SetValue(CommandTargetProperty, value); }
}
public static readonly DependencyProperty CommandTargetProperty =
DependencyProperty.Register("CommandTarget", typeof(UIElement), typeof(ExecuteCommand), null);
protected override void Invoke(object parameter)
{
if (Command is RoutedCommand)
{
var routedCommand = Command as RoutedCommand;
var commandTarget = CommandTarget ?? AssociatedObject as UIElement;
if (routedCommand.CanExecute(CommandParameter, commandTarget))
routedCommand.Execute(CommandParameter, commandTarget);
}
else
{
if (Command.CanExecute(CommandParameter))
Command.Execute(CommandParameter);
}
}
}
Если вы не используете маршрутизируемые команды, а используете, скажем, MVVM RelayCommand, вам не нужно ExecuteCommand
, и вы можете использовать InvokeCommandAction
вместо этого.
В этом примере используется поведение. Если вы не знакомы с поведением, установите Expression Blend 4 SDK и добавьте это пространство имен:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
и добавьте System.Windows.Interactivity
к вашему проекту.