15

コマンドをビュー モデルに抽象化することは、XAML/MVVM プロジェクトの貴重な実践です。わかりました。そして、WinRT に ICommand が表示されます。しかし、どのように実装するのでしょうか? 実際に動作するサンプルは見つかりませんでした。誰でも知っていますか?

4

5 に答える 5

20

私の一番のお気に入りは、Microsoft Patterns and Practices チームが提供する DelegateCommand です。これにより、入力されたコマンドを作成できます。

MyCommand = new DelegateCommand<MyEntity>(OnExecute);
...
private void OnExecute(MyEntity entity)
{...}

また、CanExecuteChanged イベントを発生させる方法も提供します (コマンドを無効/有効にするため)。

MyCommand.RaiseCanExecuteChanged();

コードは次のとおりです。

public class DelegateCommand<T> : ICommand
{
    private readonly Func<T, bool> _canExecuteMethod;
    private readonly Action<T> _executeMethod;

    #region Constructors

    public DelegateCommand(Action<T> executeMethod)
        : this(executeMethod, null)
    {
    }

    public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
    {
        _executeMethod = executeMethod;
        _canExecuteMethod = canExecuteMethod;
    }

    #endregion Constructors

    #region ICommand Members

    public event EventHandler CanExecuteChanged;

    bool ICommand.CanExecute(object parameter)
    {
        try
        {
            return CanExecute((T)parameter);
        }
        catch { return false; }
    }

    void ICommand.Execute(object parameter)
    {
        Execute((T)parameter);
    }

    #endregion ICommand Members

    #region Public Methods

    public bool CanExecute(T parameter)
    {
        return ((_canExecuteMethod == null) || _canExecuteMethod(parameter));
    }

    public void Execute(T parameter)
    {
        if (_executeMethod != null)
        {
            _executeMethod(parameter);
        }
    }

    public void RaiseCanExecuteChanged()
    {
        OnCanExecuteChanged(EventArgs.Empty);
    }

    #endregion Public Methods

    #region Protected Methods

    protected virtual void OnCanExecuteChanged(EventArgs e)
    {
        var handler = CanExecuteChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    #endregion Protected Methods
}
于 2012-08-15T05:23:14.920 に答える
3

RelayCommandクラスを確認してください(METRO コードのみ)。NotifyPropertyChangedクラスはここにあります。このNotifyPropertyChangedクラスは、バインディングを許可しCanExecute、で更新するためにのみ使用されますRaiseCanExecuteChanged

元のリレー コマンド クラスは、ここにあります。

于 2012-08-14T23:14:24.793 に答える
2

残念ながら、それを実装するネイティブ クラスはないようです。自分で実装する場合、インターフェイスはそれほど複雑ではありません。人気のあるMVVM Liteツールキットには、独自のバージョンのRelayCommandが含まれています。[参照] を右クリックして [NuGet パッケージの管理] を選択すると、MVVM Lite をプロジェクトに追加できます。このオプションがない場合は、Tools -> Extensions and Updatesで Nuget を有効にします。

于 2012-08-15T02:24:05.097 に答える
0

https://code.msdn.microsoft.com/windowsapps/Working-with-ICommand-690ba1d4でこの本当に良い例を見つけました

<Page.Resources> 
        <local:MyCommandsCollection x:Key="MyCommands" /> 
</Page.Resources> 

   <Button Width="280" 
            Height="59" 
            Margin="513,280,0,0" 
            HorizontalAlignment="Left" 
            VerticalAlignment="Top" 
            Command="{Binding MyFirstCommand}" 
            CommandParameter="{Binding Text, 
                                       ElementName=myTextBox}" 
            Content="Execute Command" /> 


public class MyCommandsCollection 
{ 
    public MyCommand MyFirstCommand 
    { 
        get { return new MyCommand(); } 
    } 
} 

public class MyCommand : ICommand 
    { 
        public bool CanExecute(object parameter) 
        { 
            return true; 
        } 

        public event EventHandler CanExecuteChanged; 

        public async void Execute(object parameter) 
        { 
            MessageDialog message = new MessageDialog( 
                "The command is executing, the value of the TextBox is " + parameter as String); 
            await message.ShowAsync(); 
        } 
    }

これを x:Bind で試してみたところ、うまく機能しました。必要なのは、「MyCommand」クラスの新しいインスタンスを返す ViewModel のプロパティを公開することだけで、すべて問題ありません。

XAML で DataContext を設定しているので、"MyCommandCollection" のものをいじる必要はありませんでした。コンパイルされたバインディングです。

于 2015-09-29T20:57:20.197 に答える