1

我目前正在使用 MVVM 模式开发 Windows 商店应用程序。ViewModel 实现了视图使用的几个命令。在某些情况下,我希望视图触发的不仅仅是一个命令。因此,我创建了一个从 ICommand 派生的 CommandGroup 类,并拥有一个可观察的命令集合。为了能够使用 XAML 填充此集合,我创建了另一个名为 CommandProxy 的类,它派生自 DependencObject 并且还实现了 ICommand。

这个想法是在视图中支持这样的东西:

<Button Content="Test">
   <Button.Command>
      <vm:CommandGroup>
         <vm:CommandGroup.Commands>
            <vm:CommandProxy Command="{Binding Command1}" CommandParameter="{Binding ElementName=Object1}"/>
            <vm:CommandProxy Command="{Binding Command2}" CommandParameter="{Binding ElementName=Object2}"/>
            <vm:CommandProxy Command="{Binding Command3}" CommandParameter="{Binding ElementName=Object3}"/>
         </vm:CommandGroup.Commands>
      </vm:CommandGroup>
   </Button.Command>
</Button>

进行语法检查时一切看起来都很好,但绑定在运行时没有解析。假设 ViewModel 实现命令 MyCommand 并且视图包含一个名为 MyElement 的元素,可以使用以下示例重现这一点:

<Button Content="Test">
   <Button.Command>
      <vm:CommandProxy Command="{Binding MyCommand}" CommandParameter="{Binding ElementName=MyElement}"/>
   </Button.Command>
</Button>

这是可用于重现问题的 CommandProxy 类的简化版本:

public class CommandProxy : DependencyObject, ICommand
{
    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(object), typeof(CommandProxy), new PropertyMetadata(null));

    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(CommandProxy), new PropertyMetadata(null));

    /// <summary>
    /// Command
    /// </summary>
    public ICommand Command
    {
        get
        {
            return (ICommand)GetValue(CommandProperty);
        }

        set
        {
            SetValue(CommandProperty, value);
        }
    }

    /// <summary>
    /// Command Parameter
    /// </summary>
    public object CommandParameter
    {
        get
        {
            return GetValue(CommandParameterProperty);
        }

        set
        {
            SetValue(CommandParameterProperty, value);
        }
    }

    /// <summary>
    /// Event used to singnal that CanExecute has changed
    /// </summary>
    public event EventHandler CanExecuteChanged;

    /// <summary>
    /// Create new CommandGroupElement
    /// </summary>
    public CommandProxy()
    {
    }

    /// <summary>
    /// Determine whether command can be executed
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public bool CanExecute(object parameter)
    {
        if (Command != null)
            return Command.CanExecute(CommandParameter);
         return false;
    }

    /// <summary>
    /// Execute Command
    /// </summary>
    /// <param name="parameter">Parameter</param>
    public void Execute(object parameter)
    {
        if (Command != null)
            Command.Execute(CommandParameter);
    }

    /// <summary>
    /// Raise CanExecuteChanged event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void raiseCanExecuteChanged()
    {
        raiseCanExecuteChanged(this, EventArgs.Empty);
    }

    /// <summary>
    /// Raise CanExecuteChanged event
    /// </summary>
    /// <param name="sender">Parameter</param>
    /// <param name="e"></param>
    protected void raiseCanExecuteChanged(object sender, EventArgs e)
    {
       if (CanExecuteChanged != null)
           CanExecuteChanged(this, EventArgs.Empty);
    }
}

有没有人可以告诉我我做错了什么或解释我为什么这不起作用?

亲切的问候

托马斯

4

0 回答 0