C#でMVVMパターンのアプリを作ってみた(Microsoft.TeamFoundation.Controls無し編)

Microsoft.TeamFoundation.Controls.dll(Microsoft.TeamFoundation.MVVM名前空間)の再配布が不可ということなので、以前作ったアプリをdllの参照追加無しで作り直してみました。 こちらのサイトを参考にさせていただきました。

目次

  1. 試してみた
    1. どういうアプリ?
    2. サイトで公開されているクラスを流用させていただく
    3. View
    4. ViewModel
    5. Model
    6. 動かしてみた
  2. まとめ

試してみた

どういうアプリ?

下記のようなアプリです。

  • テキストボックスに入力した文字列を、ボタンを押したら過去に入力済みの文字列に付け加える形で保持します。

  • ラベルに保持している入力済み文字列を表示します。

  • 入力済み文字列をクリアするボタンを付けます。 160125-2-01

サイトで公開されているクラスを流用させていただく

こちらのサイトで公開されている2つの基本クラス(ViewModelBase, DelegeteCommand)を使わせていただきました。(Apache License Version 2.0) コードはここには書きません。作法にあわせて、ソリューションエクスプローラーでCommonというフォルダを作ってそこにこれらのクラスを置きます。

View

Viewは変更ありません。今回はコード部分だけの変更ですので。これがMVVMのメリットなのでしょうか。

ViewModel

ViewModelのコードは、ちょっと変わりました。

// using Microsoft.TeamFoundation.MVVM; を削除しました
using System.Windows.Input;
using mvvm_trial.Common; // 【変更箇所】Commonフォルダのクラスファイルを参照する

namespace mvvm_trial
{
    public class MainWindowViewModel : ViewModelBase //【変更箇所】ViewModelBaseクラスを継承します 偶然にも変更前と同じ名前なので、実際はコードの書き換え不要でした
    {
        // Addボタンとのバインド
        private ICommand _AddItem;
        public ICommand AddItem
        {
            get
            {
                if (_AddItem == null)
                {
                    _AddItem = new DelegateCommand(ExecuteAddItem); // 【変更箇所】使用するクラスをDelegateCommandに変更します
                }
                return _AddItem;
            }
        }
        private void ExecuteAddItem()
        {
            _stocker.stockedItem = _stocker.stockedItem + InputText;
            InputText = string.Empty;
            RaisePropertyChanged("StoredText");
        }

        // Resetボタンとのバインド
        private ICommand _ResetItem;
        public ICommand ResetItem
        {
            get
            {
                if (_ResetItem == null)
                {
                    _ResetItem = new DelegateCommand(ExecuteResetItem); // 【変更箇所】使用するクラスをDelegateCommandに変更します
                }
                return _ResetItem;
            }
        }
        private void ExecuteResetItem()
        {
            _stocker.stockedItem = string.Empty;
            RaisePropertyChanged("StoredText");
        }

        // データの場所を保管するためのフィールドとプロパティ
        private DataStock _stocker;
        public DataStock Stocker
        {
            set
            {
                _stocker = value;
            }
        }

        // テキストボックスとのバインド
        private string _InputText;
        public string InputText
        {
            get { return _InputText; }
            set
            {
                _InputText = value;
                RaisePropertyChanged("InputText");
            }
        }

        // ラベルとのバインド
        public string StoredText
        {
            get
            {
                return _stocker.stockedItem;
            }
        }
    }
}

RaisePropertyChanged()メソッドもMicrosoft.TeamFoundation.MVVMと今回使用したViewModelBaseクラスで同じ名前になっているので、コードを書き換えしないでそのまま使えました。

Model

Modelは名前空間の変更に伴う修正はありませんでした。 名前空間と関係ないのですが、MainWindow.xaml.cs(MainWindowのコードビハインド)にコードを書いているのもMVVM的にどうかと思いまして、修正しました。 まず、App.xaml.csにApplication_Startupイベントを追加します。そして、MainWindow.xaml.csに書いたコードを移動します。で、MainWindowのインスタンスを作って表示します。

using System.Windows;

namespace mvvm_trial
{
    public partial class App : Application
    {
        public DataStock stocker = new DataStock(); // データ用のインスタンスの生成

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            stocker.stockedItem = string.Empty; // データの初期化
            MainWindowViewModel mainWindowVM = new MainWindowViewModel(); // ViewModelの生成
            mainWindowVM.Stocker = stocker; // ViewModelへデータ用インスタンスの「参照」を渡す

            MainWindow mainWindowV = new MainWindow();
            mainWindowV.DataContext = mainWindowVM; // ViewModelとViewをバインド
            mainWindowV.Show();
        }
    }
}

次にapp.xamlを書き換えます。Application要素のStartupUri属性を削除して、Startup属性を追加します。

<Application x:Class="mvvm_trial.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:mvvm_trial"
             Startup="Application_Startup">
    <Application.Resources>

    </Application.Resources>
</Application>

動かしてみた

修正前と同様に動作しました。

まとめ

MVVMを推しているのなら、C#でのMVVMを実現しようとしたら必ず必要になるクラスは、.Netの標準に入れて欲しいです。 試した環境は下記です。

  • Microsoft Visual Studio 2015 Express for Windows Desktop (C#)

公開日

広告