0

I want to have a window level KeyBinding with command paramter as window itself.

e.g.

<KeyBinding Command="{Binding CloseCommand}" CommandParameter="{Binding ElementName=mainWindow}" Key="Esc"/>

Binding works, but paramter comes in as null. What's the work around?

Following is my Command:`

public class DelegateCommand : ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

    public DelegateCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    public DelegateCommand(Action<object> execute,
                   Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("Action excute is null");
        _execute = execute;
        _canExecute = canExecute;
    }

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
2
  • What kind of Command you are using? Commented Jul 14, 2017 at 8:42
  • Does your Window has a name and how does your command look like? And because I'm snoopy: why do you want to use the window as a parameter? What are you wanna do? Commented Jul 14, 2017 at 8:43

2 Answers 2

1

Actually this working for me - but i am using the RelayCommand<FrameworkElement> of [MVVM Light Toolkit1.

<Window.InputBindings>
    <KeyBinding Command="{Binding MyCommand, ElementName=MainRoot}" CommandParameter="{Binding ElementName=MainRoot}" Key="Esc"/>
</Window.InputBindings>

In my case the Command comes from a DependencyProperty, but that shouldn't make a big difference.

public RelayCommand<FrameworkElement> MyCommand
{
    get { return (RelayCommand<FrameworkElement>)GetValue(MyCommandProperty); }
    set { SetValue(MyCommandProperty, value); }
}

// Using a DependencyProperty as the backing store for MyCommand.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyCommandProperty =
    DependencyProperty.Register("MyCommand", typeof(RelayCommand<FrameworkElement>), typeof(MainWindow), new PropertyMetadata(null));




public MainWindow()
{
    InitializeComponent();
    MyCommand = new RelayCommand<FrameworkElement>(DoSthYo);
}

public void DoSthYo(FrameworkElement fwE)
{
    var x = fwE; 
}

So because this is working - i think its your Command that does not support CommandParameter maybe.

Sign up to request clarification or add additional context in comments.

5 Comments

Edited my Q to include the command, going to try your implementation, I am not using MVVM Toolkit.
This is interesting, actully my command directly on Button for example, picks up the element binding as CommandParameter .e.g following work, Inputbinding doesn't <Button Content="Close" Width="100" HorizontalAlignment="Right" Command="{Binding CloseCommand}" CommandParameter="{Binding ElementName=mainWindow}"/>
Works! Thanks, RelativeSource with my Command example din't - What's the difference?
Maybe because Window itself looking for a Window as parent. Because the KeyBinding is directly under Window.
0

My advice is to use a RelativeSource in your CommandParameter binding:

<Window.InputBindings>
    <KeyBinding Command="{x:Static local:CloseWindowCommand.Instance}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Key="Esc" />
</Window.InputBindings>

In this way your binding can be independant from the name of your Window. Then you can create a static command for closing each window of your application:

public class CloseWindowCommand : ICommand
{
    public static readonly ICommand instance = new CloseWindowCommand();
    public event EventHandler CanExecuteChanged;

    private CloseWindowCommand()
    {
    } 

    public bool CanExecute(object parameter)
    {
        return (parameter is Window);
    }

    public void Execute(object parameter)
    {
        Window win;
        if (CanExecute(parameter))
        {
            win = (Window)parameter;
            win.Close();
        }
    }
}

I hope it can help you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.