しらとりのブログ

社会人ひよこプログラマのtil

WPFで画面とロジックを分離する(ICommand 実装編)

描画とドメインロジックを一緒の場所に書くとすぐスパゲッティができます。(体験談)

VisualStudioのイベントハンドラ自動生成機能はすごく直感的にGUIプログラミングができますが、代償としてイベントハンドラが生成されるコードビハインドが非常に大きくなります。 WPFではイベントハンドラを作成するのではなく、別の場所にコマンドというものを作成してコードビハインドからコードを排除します。


ViewModelクラスを作る

WPFにおけるコードビハインドは、ウィンドウやユーザコントロールを作成したときに自動的にできる*.xaml.csファイルです。ここにコードを書きたくないので新しくクラスを作成します。ViewModelクラスです。

/// MainWindowViewModel.cs
class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        this.HogeCommand = new RelayCommand(hogeCommand)
    }

    public ICommand HogeCommand {get; private set;}

    private void hogeCommand()
    {
        // ほげほげ
    }
}

Viewに対応するViewModelを紐づける

そして、コードビハインドには次の1行を書いてViewModelと紐づけます。基本的にこの1行以外はコードビハインドに書かないと思ってよいです。(もちろん例外はあります。)

public partial class MainWindowView: Window
{
    public MainWindowView()
    {
        InitializeComponent();
        this.DataContext = new MainWindowViewModel();
    }
}

ViewからViewModelのコマンドを利用する

そして、Viewのボタンにコマンドをバインドします。

<Button Content="ほげほげ" Command="{Binding HogeCommand }" />

これで、ほげほげボタンをクリックすると、MainWindowViewModelのhogeCommandが実行されるようになりました。

ここで唐突にでてくるRelayCommandは通常MVVMインフラに含まれます。DelegateCommandみたいな名前の時もあります。これについてはまた別記事で詳しく。。。