WPF Commandについて - TakanoriMukai/MyNotes GitHub Wiki

Commandとは??

MVVMパターンにおいて、ViewとModelを疎結合にしつつ、イベント処理を行うための仕組み。 コードビハインドに何も書かなくても処理を実行させられる。

とりあえず動かしてみる

【参考】http://takamints.hatenablog.jp/entry/why-using-commands-in-wpf-mvvm

Command01.cs

    /// <summary>
    /// ICommandインタフェースを実装したクラス。
    /// </summary>
    public class Command01 : ICommand
    {
        private bool isBusy = false;
        public bool IsBusy
        {
            get { return isBusy; }
            set
            {
                isBusy = value;
                CanExecuteChanged?.Invoke(this, new EventArgs());
            }
        }

        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            Console.WriteLine("CanExecute [isBusy]" + IsBusy);
            return !IsBusy;
        }

        public async void Execute(object parameter)
        {
            Console.WriteLine("Execute");
            IsBusy = true;
            await Task.Run(() => RunHeavyMethodParallel());
            Console.WriteLine("Execute Complete!");
            IsBusy = false;
        }
        public Task RunHeavyMethodParallel()
        {
            // 重い処理
        }
    }

MainViewModel.cs

    // メイン画面のViewModel
    public class MainViewModel
    {
        // MainWindowで呼び出したいコマンドを定義し、xamlでバインディングする。
        // バインド時はプロパティ名を指定する。
        public Command01 Command01 { get; } = new Command01();
    }
    // ※PropertyChanged()を実装しなくても動く

MainWindow.xaml

<Window x:Class="CommandTest01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CommandTest01"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    
    <Grid>
        <!-- ViewModelで定義したプロパティCommand01をバインディング -->
        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Height="35" Margin="10,10,0,0" VerticalAlignment="Top" Width="91"
                Command="{Binding Command01}"/>
    </Grid>
</Window>

Viewの内容を操作してみる

ViewのWindowにNameを定義してCommandParameterでインスタンスを渡す。

MainWindow.xaml

<Window x:Class="CommandTest01.MainWindow"
        ...
        Name="mainWindow">
        ...
        <!-- CommandParameterでこのMainWindowのインスタンスを渡す-->
        <Button x:Name="button1" Content="Button" HorizontalAlignment="Left" Height="35" Margin="10,50,0,0" VerticalAlignment="Top" Width="91"
                Command="{Binding Command02}" CommandParameter="{Binding ElementName=mainWindow}"/>
</Window>

Command02.cs

    public class Command02 : ICommand
    {
        ...
        public void Execute(object parameter)
        {
            var mainWindow = parameter as MainWindow;
            mainWindow.textBox.Text = "Button Clicked!";
        }
    }
⚠️ **GitHub.com Fallback** ⚠️