コマンドをビュー モデルに抽象化することは、XAML/MVVM プロジェクトの貴重な実践です。わかりました。そして、WinRT に ICommand が表示されます。しかし、どのように実装するのでしょうか? 実際に動作するサンプルは見つかりませんでした。誰でも知っていますか?
5 に答える
私の一番のお気に入りは、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
}
RelayCommandクラスを確認してください(METRO コードのみ)。NotifyPropertyChanged
クラスはここにあります。このNotifyPropertyChanged
クラスは、バインディングを許可しCanExecute
、で更新するためにのみ使用されますRaiseCanExecuteChanged
。
元のリレー コマンド クラスは、ここにあります。
残念ながら、それを実装するネイティブ クラスはないようです。自分で実装する場合、インターフェイスはそれほど複雑ではありません。人気のあるMVVM Liteツールキットには、独自のバージョンのRelayCommandが含まれています。[参照] を右クリックして [NuGet パッケージの管理] を選択すると、MVVM Lite をプロジェクトに追加できます。このオプションがない場合は、Tools -> Extensions and Updatesで Nuget を有効にします。
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" のものをいじる必要はありませんでした。コンパイルされたバインディングです。