WPF CommandParameter имеет значение NULL при привязке к элементу

Я пытаюсь привязать текстовое поле к Commandparameter. Однако при вызове CanExecute переданный параметр имеет значение null. Изменение текста также не вызывает CanExecute.

Мой вариант использования действителен?

Посмотреть

<Window x:Class="PlayButtonCommandParameter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:playButtonCommandParameter="clr-namespace:PlayButtonCommandParameter"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <playButtonCommandParameter:TestViewModel x:Key="vm"/>
  </Window.Resources>
    <StackPanel DataContext="{StaticResource vm}">
      <TextBox Name="Test">Hello</TextBox>
      <Button Content="Element Name Click" 
              Command="{Binding TestCommand}" 
              CommandParameter="{Binding ElementName=Test, Path=Text}"></Button>
      <Button Content="RelativeSource Click" 
              Command="{Binding RelativeSourceCommand}" 
              CommandParameter="{Binding 
                                  RelativeSource={RelativeSource AncestorType=StackPanel}, 
                                  Path=Children[0].Text}"></Button>
    </StackPanel>
</Window>

ViewModel

public class TestViewModel : INotifyPropertyChanged
{
    private readonly ICommand testCommand = new TestCommand();

    public ICommand TestCommand
    {
        get { return testCommand; }
    }

    private readonly ICommand relativeSourceCommand = new TestCommand();

    public ICommand RelativeSourceCommand
    {
        get { return relativeSourceCommand; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

команда

public class TestCommand : ICommand
{
    public void Execute(object parameter)
    {
        Clipboard.SetData(DataFormats.Text, parameter);
    }

    public bool CanExecute(object parameter)
    {
        var text = parameter as string;

        return !string.IsNullOrEmpty(text);
    }

    public event EventHandler CanExecuteChanged;
}

1 ответ

Нет, ваши ожидания не оправдались. Первый:

Изменение текста также не вызывает CanExecute

никто не собирается звонить вашему CanExecute обработчик, если вы не уволите CanExecuteChanged событие в вашем ICommand. В вашем случае вам придется справиться с TextBoxTextChanged событие и поднять CanExecuteChanged из вашего ICommand реализация.

Для этого простого случая я бы предложил вам использовать экземпляр RoutedCommand вместо. Существует CommandManager, который прослушивает изменения в пользовательском интерфейсе и поднимает CanExecuteChanged событие для вас.

Просто следуйте этим простым шагам Как: создать RoutedCommand

Другие вопросы по тегам