LoginSignup
7
12

More than 5 years have passed since last update.

【WPF】リファクタリングで学ぶMVVM、Prism ー はじめに

Last updated at Posted at 2019-03-22

はじめに

WPF、MVVM、Prismのそれぞれの技術要素を、既に作成されたアプリケーションをリファクタリングを行いながら、体系的に学んでいければという記事となります。
リファクタリングを行ううえで最小限の項目しか扱いませんので、WPFやPrismの内容を詳細に学んでいく、とい趣旨ではないことをご了承ください。
※サンプルで用いているコンポーネントはInfragistics社のWPF製品を採用している箇所がありますので、動作をお試しいただく際にはコンポーネントのインストールが必要(Trial版あり)となります。

どんなアプリケーションをリファクタリング?

社員情報を管理するような簡単なアプリケーションを作りました。取り扱う情報としては、名前、年齢という基本的な項目のみ。
Capture.gif

仕様

  • 左側のエリアにて、
    • 社員情報一覧を表示
    • レコードの増減は、"行追加","行削除"のボタンより実行
  • 右側のエリアに、
    • 社員情報を修正するエリア(XamPropertyGrid)が表示
    • 編集した内容は'編集内容を確定"にて実行

ソースコード

  • バインディングを一切行わらず
  • すべてイベントのみで処理し、
  • 主要な実装は MainWindow.xaml / MainWindow.xaml.cs の2ファイルのみ です。
MainWindow.xaml
<Window xmlns:igWPF="http://schemas.infragistics.com/xaml/wpf"  xmlns:ig="http://schemas.infragistics.com/xaml"  x:Class="TryRefactoring.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:TryRefactoring"
        mc:Ignorable="d"
        Title="MainWindow" Height="400" Width="900">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <!-- 一覧エリア -->
        <StackPanel  Grid.Column="0" Margin="10">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Button Grid.Column="0" Click="addBtnClick">行追加</Button>
                <Button Grid.Column="1" Click="deleteBtnClick">行削除</Button>
            </Grid>
            <igWPF:XamDataGrid x:Name="xamDataGrid" RecordActivated="XamDataGrid_RecordActivated" Height="300">
                <igWPF:XamDataGrid.FieldSettings>
                    <igWPF:FieldSettings AllowEdit="False" />
                </igWPF:XamDataGrid.FieldSettings>
            </igWPF:XamDataGrid>
        </StackPanel>

        <!-- 編集エリア -->
        <StackPanel Grid.Column="1" Margin="10">
            <Button Click="fixBtnClick">編集内容を確定</Button>
            <ig:XamPropertyGrid  x:Name="xamPropGrid" />
        </StackPanel>

    </Grid>
</Window>

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;
        }

    }
}

ファイル構成

TryRefactoring
│ MainWindow.xaml
│ MainWindow.xaml.cs
├─Assets
│ sampledata.json
├─Data
│ SampleData.cs

GitHubはこちら。
https://github.com/furugen/WPF-Try-Refactoring/tree/edition1

どうやってリファクタリングしていく?

まずは、MVVMの土台を作成し、適切なコントロールの分割化。そのあとにPrismとしての最適化を行っていきます。
各項目については、目次をご参照くださいませ。

目次(予定)

WPF標準機能 + MVVM あれこれ
1. バインディング (View)(ViewModel)(Model)
2. ViewModel,Modelの作成 (View)(ViewModel)
3. ユーザコントロールの分割 (View)(ViewModel)
4. イベントのコマンド化 (ViewModel)

Prism
5. Prism導入
6. Region
7. Module化

まとめ

次の記事から目次のメニューを消化していき、MVVM,Prism向けにリファクタリングしていきます。
まずは、ViewModelの外枠から作っていきますよー。

次の記事

【WPF】リファクタリングで学ぶMVVM、Prism。その① ~ MVVM観点で処理を切り分ける ~

7
12
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
7
12