如何创建具有更改控件 Header 值功能的 RelayCommand?

How to create RelayCommand that has functionality that changes the Header value of the control?

RoutedUI命令具有更改控件 Header 值的功能。

例如,下面的代码会将 MenuItem 的 Header 值更改为 "Cut"。

<MenuItem Command="ApplicationCommands.Cut"/>

但如果使用 RelayCommand 而不是 "ApplicationCommands.Cut",则 MenuItem 的 Header 值不会改变。

public static class MenuActionCommands
{
    public static MainWindow parentWindow { get; set; }

    public static readonly RelayCommand NewProject = new RelayCommand(NewProjectExecute, NewProjectCanExecute);
}

<MenuItem Command="commands:MenuActionCommands.NewProject"/>

我的目标是将 RelayCommand 功能与更改 UI Header 值的 RoutedUICommand 功能结合起来。

例如,我想创建下面的命令并使用它。

public class RelayUICommand : RelayCommand
{
    // include functionality that changes control Header value.
}

谁能告诉我应该怎么做才能解决这个问题?

感谢阅读。

MenuItem.Command 绑定到 RoutedUICommand 并设置 RoutedUICommand.Text 属性 时,会自动设置 MenuItem.Header 值。

所以你必须使用 RoutedUICommand 并设置 Text 属性。然后将调用委托给您的 RelayCommand 实例:

public partial class MyUserControl : UserControl
{
  public static RoutedUICommand NewProjectRoutedUICommand = new RoutedUICommand() { Text = "Create New Project" };    

  // Perhaps this command is exposed by a view model
  public static RelayCommand NewProjectRelayCommand = new RelayCommand(NewProjectExecute, NewProjectCanExecute);

  public MyUserControl()
  {
    this.CommandBindings.Add(new CommandBinding(NewProjectCommand, ExecutedNewProjectRoutedUICommand, CanExecuteNewProjectRoutedUICommand));
  }

  private void ExecutedNewProjectRoutedUICommand(object sender, ExecutedRoutedEventArgs e)
  {
    // Delegate to RelayCommand instance
    MyUserControl.NewProjectRelayCommand.Execute(e.Parameter);
  }

  private bool CanExecuteNewProjectRoutedUICommand(object sender, CanExecuteRoutedEventArgs e)
  {
    // Delegate to RelayCommand instance
    return MyUserControl.NewProjectRelayCommand.CanExecute(e.Parameter);
  }
}

用法

<MenuItem Command="{x:Static MyUserControl.NewProjectRoutedUICommand" /> 

或者将 Text 属性 添加到您的 RelayCommand 并将其绑定到 MenuItem.Header 属性:

public class RelayUICommand : RelayCommand
{ 
  public RelayUICommand(Action<object> executeDelegate, Func<object, bool> canExecuteDelegate, string description) : base(executeDelegate, canExecuteDelegate)
  {
    this.Text = description;
  }

  public RelayUICommand(Action<object> executeDelegate, Func<object, bool> canExecuteDelegate) => this(executeDelegate, canExecuteDelegate, string.Empty);

  public string Text { get; set; }
}

用法

<MenuItem Command="{x:Static MenuActionCommands.NewProject}" 
          Header="{x:Static MenuActionCommands.NewProject.Text}" /> 

可重用版本(将自动设置MenuItem.Header

<!-- Use in conjunction with the RelayUICommand -->
<Style TargetType="MenuItem">
  <Setter Property="Header" 
          Value="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text} />
</Style>

<MenuItem Command="{x:Static MenuActionCommands.NewProject}" />