はじめに
下記の記事の続きとなります。
【WPF】リファクタリングで学ぶMVVM、Prism ー はじめに
この記事では、MainWindow.xaml.csを対象にMVVM観点でどの層に処理を任せるか?を学んでいきます。
この章で達成すること
- コードビハインド(MainWindow.xaml.cs)に記載されたロジックをMVVM観点で処理の責務を分ける。
この章で得られるもの
- MVVMの観点で、処理の責務を決定できる。
責務分割の基準
MainWindow.xaml.csを分割するまえに、MVVMの各層の役割を簡単にご紹介します。
Viewの責任
- 画面に表示する構造と外見を定義
ViewModelの責任
- プレゼンテーションレイヤで扱うデータのカプセル化
- プレゼンテーションロジック(イベントのハンドルなど)
- Viewに表示するためのデータストアを定義
Modelの責任
- ビジネスロジック
- ビジネスロジックで扱うデータのカプセル化
- ViewおよびViewが行う役割以外の全て
詳細については、こちらに非常に綺麗にまとめられているのでご参照ください。
https://docs.microsoft.com/en-us/previous-versions/msp-n-p/gg405484(v=pandp.40)#sec1
MainWindow.xaml.csの処理を列挙
MainWindow.xaml.csコードがこちらです。
namespace TryRefactoring
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
private string JSON_FILE_PATH = "./Assets/sampledata.json";
public MainWindow()
{
InitializeComponent();
// Jsonをシリアライズ化してサンプルデータを設定
this.xamDataGrid.DataSource = LoadJsonFile();
}
private List<SampleData> LoadJsonFile()
{
// Jsonファイルを読み込み、デシリアライズ化し、SampleDataに設定します。
string fileContent = System.IO.File.ReadAllText(JSON_FILE_PATH);
return JsonConvert.DeserializeObject<List<SampleData>>(fileContent);
}
private void addBtnClick(object sender, RoutedEventArgs e)
{
// 行を追加する
List<SampleData> records = this.xamDataGrid.DataSource as List<SampleData>;
records.Add(new SampleData());
this.xamDataGrid.DataSource = null;
this.xamDataGrid.DataSource = records;
}
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;
}
private void fixBtnClick(object sender, RoutedEventArgs e)
{
SampleData editData = this.xamPropGrid.SelectedObject as SampleData;
List<SampleData> records = this.xamDataGrid.DataSource as List<SampleData>;
SampleData targetData = records.First(data => data.Id == editData.Id);
// 編集内容を反映
targetData.Age = editData.Age;
targetData.Name = editData.Name;
// XamDataGridに反映
this.xamDataGrid.DataSource = null;
this.xamDataGrid.DataSource = records;
// データソース反映時に選択行が解除されるため、再設定
this.xamDataGrid.SelectedDataItem = targetData;
}
private void XamDataGrid_RecordActivated(object sender, Infragistics.Windows.DataPresenter.Events.RecordActivatedEventArgs e)
{
// 選択行のオブジェクトをXamPropertyGridに表示
xamPropGrid.SelectedObject = this.xamDataGrid.ActiveDataItem;
}
}
}
ソースコードをもとに、MainWindow.xaml.csが行っている処理を下記のように列挙しました。
- コントロールへ、データの反映
- グリッド(XamDataGrid)への社員情報データを反映
- グリッド(XamDataGrid)の選択行の内容を編集エリアに反映
- イベント処理
- 行追加ボタンクリック時のイベントのハンドリング
- 行削除ボタンクリック時のイベントのハンドリング
- 編集内容を確定ボタンクリック時のイベントのハンドリング
- データの削除、追加、更新
- 社員情報データをストア
- 社員情報データにレコードを追加
- 社員情報データからレコードを削除
- 編集内容(XamPropetyGrid)を元に、社員情報データを更新
- 外部からのデータ読込
- JSONファイル(社員情報)の読込
- JSONファイル(社員情報)の読み込んだ内容をクラス化
MainWindow.xaml.csの債務分割
それでは、責務分割の基準を参考に、それぞれの処理を各層に分類してみましょう。
- コントロールへのデータを表示
- グリッド(XamDataGrid.)への社員情報データを反映
- グリッド(XamDataGrid)の選択行の内容を編集エリアに反映
[振り分け]
プレゼンテーションレイヤで扱うデータを定義するため、 ViewModel で対応します。
- イベント処理
- 行追加ボタンクリック時のイベントのハンドリング
- 行削除ボタンクリック時のイベントのハンドリング
- 編集内容を確定ボタンクリック時のイベントのハンドリング
[振り分け]
ユーザインタラクションの処理のため、 ViewModel で対応します。
- データの削除、追加、更新
- 社員情報データをストア
- 社員情報データにレコードを追加
- 社員情報データからレコードを削除
- 編集内容(XamPropetyGrid)を元に、社員情報データを更新
[振り分け]
ビジネスロジックおよびビジネスロジックで扱うデータ管理のため、 Model で対応します。
- 外部からのデータ読込
- JSONファイル(社員情報)の読込
- JSONファイル(社員情報)の読み込んだ内容をクラス化
[振り分け]
ビジネスロジックおよびビジネスロジックで扱うデータ管理のため、 Model で対応します。
まとめ
MainWindow.xaml.csの処理を列挙し、MVVMの各層への振り分けを決めました。
次の章から、ViewModelおよびModelの外枠を作り、各処理を分割していきましょー。
#次の記事