1

現在、MVVM パターンを使用して Windows ストア アプリを開発しています。ViewModel は、ビューで使用されるいくつかのコマンドを実装します。場合によっては、ビューで複数のコマンドをトリガーしたいことがあります。したがって、ICommand から派生し、監視可能なコマンドのコレクションを保持する CommandGroup クラスを作成しました。XAML を使用してこのコレクションを設定できるようにするために、DependencObject から派生し、ICommand も実装する CommandProxy という別のクラスを作成しました。

アイデアは、ビュー内で次のようなものをサポートすることです:

<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