Vinay Dwivedi
Vinay Dwivedi

Reputation: 767

Input Binding CommandParameter Bind to Window

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; }
    }

Upvotes: 0

Views: 546

Answers (2)

Il Vic
Il Vic

Reputation: 5666

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.

Upvotes: 0

Peter
Peter

Reputation: 1687

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.

Upvotes: 1

Related Questions