WPF: Bind to command from ControlTemplate

让人想犯罪 __ 提交于 2019-12-04 04:03:00

You should start by making the wrapper property for the command static and use

Command={x:Static local:MyListView.MyCustomCommand}

Generally you only want an ICommand property if the command is being set to a different value on each instance (like Button) or if it's something like a DelegateCommand/RelayCommand on a ViewModel. You should also remove all of the extra code in the getter and instead initialize the command either inline or in the static constructor and connect the CommandBinding in the control's instance constructor.

CommandBindings.Add(new CommandBinding(MyCustomCommand, binding_Executed));

**UPDATE

The RoutedCommand itself should be declared as static. ICommand instance properties are good for when an external consumer of your control is passing in a command to execute, which is not what you want here. There is also no need for a DP here and the one you're using is declared incorrectly - to be usable they need to have instance wrapper properties with GetValue/SetValue.

public static RoutedCommand ShowColumnPickerCommand
{
    get; private set;
}

static MyListView()
{        
    ShowColumnPickerCommand = new RoutedCommand("ShowColumnPickerCommand", typeof(MyListView));
}

I am not sure if this the correct way to do this. It's a bit difficult to read source code in comments, so I write this reply as an answer...

Here is the constructor of MyListView + the command binding methods:

public MyListView()
{        
    showColumnPickerCommand = new RoutedCommand("ShowColumnPickerCommand", typeof(MyListView));

    var binding = new CommandBinding();
    binding.Command = showColumnPickerCommand;
    binding.Executed += ShowColumnPicker;
    binding.CanExecute += ShowColumnPickerCanExecute;

    CommandBindings.Add(binding);
}

private void ShowColumnPicker(object sender, ExecutedRoutedEventArgs e)
{
    MessageBox.Show("Show column picker");          
}

private void ShowColumnPickerCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

The bindings are not set up in a static context. The only things that are static are the DependencyProperty for the command, and the command itself:

public static readonly DependencyProperty ShowColumnPickerCommandProperty =
    DependencyProperty.Register("ShowColumnPickerCommand", typeof(RoutedCommand), typeof(MyListView));

private static RoutedCommand showColumnPickerCommand;

public static RoutedCommand ShowColumnPickerCommand
{
    get
    {
        return showColumnPickerCommand;
    }
}

The command needs to be static to able to bind to it from the XAML like this:

<Button Command="{x:Static local:MyListView.ShowColumnPickerCommand}" />
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!