如何创建可绑定的命令代理

时间:2012-11-07 22:30:25

标签: c# mvvm windows-8 windows-runtime windows-store-apps

我目前正在使用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);
    }
}

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

亲切的问候

托马斯

0 个答案:

没有答案