びおりんのブログ

きままにアプリのできるまでを公開していきます

WPFのMVVMで電卓づくり(3)

電卓の数字ボタンを押したら出力画面が更新される仕組みを作成します
今回は仕組みのうち、数字ボタンを押してから内部データを変更する手前までの処理を作ります

下準備

下図はソリューションエクスプローラーの構成です
f:id:kazoojapan1985:20200503010317p:plain

前回時点でApp.xamlとMainView.xamlが作成されています
今回はDelegateCommand.csとMainViewModel.csを追加していきます

電卓ボタンを押した際のコマンドを登録するクラスをDelegateCommand.csに作成します

   public class DelegateCommand : ICommand
    {
        private Action<object> _Execute;
        private Func<object, bool> _CanExecute;

        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            _Execute = execute;
            _CanExecute = canExecute;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _Execute?.Invoke(parameter);
        }

        public bool CanExecute(object parameter)
        {
            return _CanExecute?.Invoke(parameter) ?? true;
        }
    }

上記クラスはユーザーインターフェースであるMainView.xaml上の各ボタンと
MainViewModel.csに持たせる予定のボタン入力を制御する処理を
コマンドで紐づけするために使用します

ボタンと入力制御を紐づけする仕組みの作成

ボタンクリックと入力制御をコマンドで紐づけする仕組みを作成します

コマンドの実装

まずはMainViewModel.csを作成し、コンストラクタにて
ボタンに紐づけするPushCommandコマンドを実装します

   class MainViewModel 
    {
        public ICommand PushCommand { get; set; }

        public MainViewModel()
        {
            this.PushCommand = new DelegateCommand(
                param => 
                {
                    MessageBox.Show(param?.ToString() ?? string.Empty);
                },
                param =>
                {
                    return true;
                });
        }
    }

PushCommandに登録する処理内容はラムダ式で記述しており
今回は簡易的に下記の処理を登録しました
「ボタンクリックが常に有効で、クリックされたボタンの文字をメッセージボックスに表示する」

コマンドの紐づけ

MainView.xamlにおけるボタンクリック時のイベントに
コードビハインドで生成したMainViewModelに実装したPushCommandを
紐づけしていきます

MainView.xaml.csにて、MainViewクラスのコンストラクタでMainViewModelを生成します

   public partial class MainView : Window
    {
        public MainView()
        {
            InitializeComponent();

            this.DataContext = new MainViewModel();
        }
    }

MainView.xamlにて、各ボタンのCommandプロパティにPushCommandを紐づけします

     <!--数字ボタン-->
        <Button Grid.Row="3" Grid.Column="1" Content="1" 
                Command="{Binding Path=PushCommand}" CommandParameter="1"/>
        <Button Grid.Row="3" Grid.Column="2" Content="2" 
                Command="{Binding Path=PushCommand}" CommandParameter="2"/>
        <Button Grid.Row="3" Grid.Column="3" Content="3" 
                Command="{Binding Path=PushCommand}" CommandParameter="3"/>
        <Button Grid.Row="2" Grid.Column="1" Content="4" 
                Command="{Binding Path=PushCommand}" CommandParameter="4"/>
        <Button Grid.Row="2" Grid.Column="2" Content="5" 
                Command="{Binding Path=PushCommand}" CommandParameter="5"/>
        <Button Grid.Row="2" Grid.Column="3" Content="6" 
                Command="{Binding Path=PushCommand}" CommandParameter="6"/>
        <Button Grid.Row="1" Grid.Column="1" Content="7" 
                Command="{Binding Path=PushCommand}" CommandParameter="7"/>
        <Button Grid.Row="1" Grid.Column="2" Content="8" 
                Command="{Binding Path=PushCommand}" CommandParameter="8"/>
        <Button Grid.Row="1" Grid.Column="3" Content="9" 
                Command="{Binding Path=PushCommand}" CommandParameter="9"/>
        <Button Grid.Row="4" Grid.Column="1" Content="0" 
                Command="{Binding Path=PushCommand}" CommandParameter="0"/>
        <Button Grid.Row="4" Grid.Column="2" Content="00" 
                Command="{Binding Path=PushCommand}" CommandParameter="00"/>

ボタンクリック結果

アプリを起動後、数字ボタン「1」をクリックするとメッセージボックスが表示され
CommandParameterに設定した「1」が表示されます
f:id:kazoojapan1985:20200503124042p:plain