必要に応じて、ViewModel を ICommand に結合するのを避けるのは非常に簡単です。おそらく悪い考えではありませんが、WPF はいつか MFC に取って代わられるでしょう。やり過ぎ?たぶん、しかしここに方法があります:
あなたの見解では:
<StackPanel>
<Button Command="{Binding Path=MyCommand}"> Do it! Kill me Now!</Button>
<TextBlock Text="{Binding Path=Message}"></TextBlock>
</StackPanel>
ViewModel を DataContext に挿入し、View Model からネイティブ コマンドの責任を負います。
public class ViewModel : INotifyPropertyChanged
{
public string Message { get; set; }
public object MyCommand { get; set; }
public void OnMyCommand(object parameter)
{
Message += "I Ran something" + Environment.NewLine;
}
public bool CanMyCommand(object parameter)
{
return true;
}
// Injected Native Command handler
public ViewModel(ICommandFactory factory)
{
MyCommand = factory.CreateInstance(OnMyCommand, CanMyCommand);
}
public event PropertyChangedEventHandler PropertyChanged;
}
プロパティ変更ハンドラーを織り込むためにFODYを使用していることに注意してください。INotifyPropertyChanged は System.dll です。
次に、このコントラクトをバインドします。
public interface ICommandFactory
{
object CreateInstance(Action<object> action, Func<object, bool> predicate);
}
...ネイティブの Command オブジェクトを提供するものに。
public class NativeCommand : ICommand
{
private readonly Action<object> _action;
private readonly Func<object, bool> _predicate;
public NativeCommand(Action<object> action, Func<object, bool> predicate)
{
_action = action;
_predicate = predicate;
}
public bool CanExecute(object parameter)
{
return _predicate(parameter);
}
public void Execute(object parameter)
{
_action(parameter);
}
public event EventHandler CanExecuteChanged;
}
public class NativeCommandFactory : ICommandFactory
{
public object CreateInstance(Action<object> action, Func<object, bool> predicate)
{
return new NativeCommand(action, predicate);
}
}
Bind<ICommandFactory>().To<NativeCommandFactory>();
ほら、切り離されたコマンド。
また、注入は最初のアプリケーションの開始時に行われることに注意してください。ViewModel は、選択した IoC コンテナーから切り離されます。