2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【WPF】リファクタリングで学ぶMVVM、Prism。その④ ~ 行削除ボタンのClick処理をリファクタリング ~

Last updated at Posted at 2019-04-03

はじめに

下記の記事の続きとなります。

【WPF】リファクタリングで学ぶMVVM、Prism。その③ ~ 行追加ボタンのClick処理をリファクタリング ~

この記事は、行削除ボタンのClick処理をリファクタリングしていきます。

リファクタリングの対象

タイトルにもある通り、行削除ボタンのイベント処理をCommandを利用して、ViewからViewMode/MOdelに責務を移管します。

image.png

ソースコードはこちらとなります。

MainView.xaml
<Button Grid.Column="1" Click="deleteBtnClick">行削除</Button>
MainWindow.xaml.cs
        private void deleteBtnClick(object sender, RoutedEventArgs e)
        {
            // 選択行を削除する。
            List<SampleData> records = this.xamDataGrid.DataSource as List<SampleData>;
            records.Remove((SampleData)this.xamDataGrid.ActiveDataItem);
            this.xamDataGrid.DataSource = null;
            this.xamDataGrid.DataSource = records;
        }

リファクタリング

処理詳細を整理

まずは、deleteBtnClickが行っている処理を整理します。

  1. 行削除ボタンがクリックされたらdeleteBtnClickメソッドの処理を実行する。
  2. XamDataGridからデータソースを取得する。
  3. XamDataGridの選択中のレコードを取得する。
  4. 取得したデータソースから選択中のレコード削除する。
  5. 更新したデータソースを再反映させる。
    これらをViewから処理移管していきましょう。

まず行削除ボタンのクリックをViewModelで感知するために、Commandの機能を利用します。あとは、Modelにレコード削除のメソッドを用意してViewModelからコールするようにするればOKです。"選択中のレコード"を取得するためにバインディングを利用してViewModelから選択行のレコード情報が取得できるようにします。

コードリファクタリング

1. XamDataGridの選択行の情報をViewModelから参照できるようにバインディング

行削除の動きとしては、選択行を削除するという仕様でした。リファクタリングにより行削除の処理をViewModelに移管するためには、選択行もViewModelから参照できる必要があります。バインディングを利用して参照できるようにしましょう。

MainWindow.xaml.cs
(SampleData)this.xamDataGrid.ActiveDataItem

まずは、MainWindowViweModelにバインディングするためのプロパティを新設します。

MainWindowViewModel.cs
public SampleData SelectedActiveDataItem { get; set; }

次に、ActiveDataItemを新設したプロパティとバインディングを設定します。

MainView.xaml
<igWPF:XamDataGrid x:Name="xamDataGrid" ...省略...
                   ActiveDataItem="{Binding SelectedActiveDataItem}">

これでMainWindowViweModelから選択行の情報が取得できるようになりました。

2. 行削除ボタンのクリック時に呼び出されるCommandを作成する。

まずは、ほぼ空のCommandクラスを作成しましょう。

RemoveCommand.cs
public class RemoveCommand : ICommand
{
    public bool CanExecute(object parameter) { return true; }
    public event EventHandler CanExecuteChanged;
    public void Execute(object parameter)
    {

    }
}

ViewModelを操作できるようコンストラクタで対象のMainWindowViewModelを取得できるようにします。

RemoveCommand.cs
    private MainWindowViewModel vm;
    public AddCommand(MainWindowViewModel viewModel)
    {
        this.vm = viewModel;
    }

Commandが実行された際に動作するExcuteメソッドで、ViewModel側で用意する行追加メソッドをコールしましょう。OnRemoveRecord()の詳細については、次の項目にて。

RemoveCommand.cs
    public void Execute(object parameter)
    {
      this.vm.OnRemoveRecord();
    }

3. 行削除ボタンのクリックイベントを削除し、2.で作成したCommandをバインディングします。

ViewModelに作成したコマンドをプロパティとして保持し、コンストラクタで初期化します。

MainWindowViewModel.cs
        public RemoveCommand RemoveCommand { get; set; }

        public MainWindowViewModel()
        {
            ...省略...
            // 行削除コマンドを追加
            this.RemoveCommand = new RemoveCommand(this);
        }

Viewの行追加ボタンをクリックイベントではなく、コマンドで処理するように変更します。先ほどViewModelに追加したRemoveCommandプロパティとバインディングしましょう。

MainView.xaml
<Button Grid.Column="1" Command="{Binding RemoveCommand}">行削除</Button>

これで、行削除ボタンがクリックされた際に、RemoveCommand.Execute()が実行されるようになりました。

4. ViewModelの行削除メソッドから、Modelが保持する社員情報削除メソッドをコールします。

コマンド実行時(RemoveCommand.Execute)から呼ばれるメソッドを実装しましょう。

MainWindowViewModel.cs
        public void OnRemoveRecord()
        {
            // 社員情報のModelから社員情報を削除する。
            this.employeeServiceModel.RemoveEmployee(this.SelectedActiveDataItem);
        }

次に、Modelに社員情報を削除するメソッドを実装します。

EmployeeServiceModel.cs
        public void RemoveEmployee(SampleData targetData)
        {
            this.Employees.Remove(targetData);
        }

では、実際に動作確認をしてみましょう。行削除ボタンをクリックした際に、XamDataGridの選択行が削除されていることを確認できればOK!!!

Capture15.gif

リファクタリング前後のコード

今回のリファクタリング前後のコードはこちらになります。

実施前
https://github.com/furugen/WPF-Try-Refactoring/tree/edition3
実施後
https://github.com/furugen/WPF-Try-Refactoring/tree/edition4

まとめ

MainWindow.xaml.csの行削除ボタンのClickに伴う処理を責務分割しました。
基本的な作業は、行追加ボタンで行ったリファクタリングと同じ作業でしたね。

次は、編集、編集の確定機能周りをリファクタリングしていきます。

#次の記事

【WPF】リファクタリングで学ぶMVVM、Prism。その⑤ ~ 編集機能周り ~

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?