WPF RightClick MouseBinding при выпуске? - PullRequest
4 голосов
/ 05 октября 2010

Как включить привязку мыши к отпусканию правой кнопки?На данный момент у меня есть следующий код в xaml, который связан с закрытием окна wpf.Проблема здесь в том, что, поскольку он реагирует на увеличение щелчка при закрытии окна, он активирует контекстное меню на рабочем столе.

<MouseBinding Command="Close" MouseAction="RightClick" />

1 Ответ

8 голосов
/ 19 февраля 2011

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 к вашему проекту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...