「MVVMモデル」の版間の差分

提供: とある社畜の頭脳整理
ナビゲーションに移動 検索に移動
(ページの作成:「WPFでアプリ作るたびに調べなおしているので、簡単に上げておきます。<br/> できるだけ簡単に説明するために、WPFのプロジェ…」)
 
8行目: 8行目:
 
デフォルトで作成される「MainWindow.xaml」がビューを定義するファイルとなります。<br/>
 
デフォルトで作成される「MainWindow.xaml」がビューを定義するファイルとなります。<br/>
 
こんな感じの中身になっているかと思います。
 
こんな感じの中身になっているかと思います。
 +
{{hcc|head=MainWindow.xaml|lang=xml|output=<Window x:Class="MVVM_Sample.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:MVVM_Sample"
 +
        mc:Ignorable="d"
 +
        Title="MainWindow" Height="450" Width="800">
 +
    <Grid>
 +
       
 +
    </Grid>
 +
</Window>}}
 +
これをベースに、テキストボックスとボタンを追加して、ボタンを押すとテキストの内容が書き換わるようなものを作ってみます。<br/>
 +
以下の様に修正して、テキストボックスとボタンを追加します。
 +
{{hcc|head=MainWindow|lang=xml|output=<Window x:Class="MVVM_Sample.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:MVVM_Sample"
 +
        mc:Ignorable="d"
 +
        Title="MainWindow" Height="450" Width="800">
 +
    <Grid>
 +
        <Grid.RowDefinitions>
 +
            <RowDefinition Height="24"/>
 +
            <RowDefinition Height="5"/>
 +
            <RowDefinition Height="24"/>
 +
            <RowDefinition/>
 +
        </Grid.RowDefinitions>
 +
        <TextBlock Grid.Row="0" Text="{Binding ViewText}"/>
 +
        <Button Grid.Row="2" Width="74" HorizontalAlignment="Right" Content="変更" Click="ButtonClick"/>
 +
    </Grid>
 +
</Window>}}
  
 +
ポイントは「TextBlock」タグの「Text」属性です。<br/>
 +
文字列を表示したい場合はここに文字列を設定しますが、今回はビューモデルを介してやり取りしたいので「Binding ViewText」と設定しています。<br/>
 +
これにより、ビューモデル側から「ViewText」プロパティで値を操作できるようになります。
 +
 +
== ビューモデル ==
 +
デフォルトでは作成されないので、適当な名前でクラスファイルを作成します。<br/>
 +
今回は「MainWindow_VM.cs」と言う名前で作成していきます。<br/>
 +
追加はソリューションエクスプローラーからプロジェクトを右クリックし、「追加」→「クラス」→「ファイル名入力」で追加することができます。<br/>
 +
追加されると以下の様な中身になっているかと思います。
 +
{{hcc|head=MainWindow_VM.cs|lang=csharp|output=using System;
 +
using System.Collections.Generic;
 +
using System.Linq;
 +
using System.Text;
 +
using System.Threading.Tasks;
 +
 +
namespace MVVM_Sample
 +
{
 +
    class MainWindow_VM
 +
    {
 +
    }
 +
}
 +
}}
 +
 +
こいつをビューモデルで使用できるように改造していきます。
 +
ポイントは…
 +
* 「System.ComponentModel」の参照を追加
 +
* 「INotifyPropertyChanged」インタフェースを実装
 +
* 「PropertyChangedEventHandler」イベントハンドラを実装
 +
* ビューの値を保持できるように、メンバ変数を追加
 +
* ビューとやり取りする用の、プロパティを追加
 +
です。
 +
 +
それでは改造していきます。
 +
{{hcc|head=MainWindow_VM.cs|lang=csharp|output=using System;
 +
using System.Collections.Generic;
 +
using System.Linq;
 +
using System.Text;
 +
using System.Threading.Tasks;
 +
using System.ComponentModel; //追加
 +
 +
namespace MVVM_Sample
 +
{
 +
    public class MainWindow_VM : INotifyPropertyChanged //インターフェースを実装
 +
    {
 +
        /// <summary>
 +
        /// イベントハンドラを追加
 +
        /// </summary>
 +
        public event PropertyChangedEventHandler PropertyChanged;
 +
 +
        /// <summary>
 +
        /// ビューの値を保持するためのメンバ変数
 +
        /// </summary>
 +
        private string m_ViewText;
 +
 +
        /// <summary>
 +
        /// デフォルトコンストラクタ
 +
        /// </summary>
 +
        public MainWindow_VM()
 +
        {
 +
            ViewText = "変更前!"; //初期値を設定
 +
        }
 +
 +
        /// <summary>
 +
        /// ビューとやり取りするためのプロパティ
 +
        /// </summary>
 +
        public string ViewText
 +
        {
 +
            get { return m_ViewText; }
 +
            set
 +
            {
 +
                m_ViewText = value;
 +
                OnPropertyChanged("ViewText"); //イベント発動
 +
            }
 +
        }
 +
 +
        /// <summary>
 +
        /// プロパティ変更イベントハンドラ
 +
        /// </summary>
 +
        /// <param name="p_PropertyName">プロパティ名</param>
 +
        public void OnPropertyChanged(String p_PropertyName)
 +
        {
 +
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(p_PropertyName));
 +
        }
 +
    }
 +
}
 +
}}
 +
詳細は省略しますが…こんな感じです。
  
 
== モデル ==
 
== モデル ==

2020年2月6日 (木) 04:14時点における版

WPFでアプリ作るたびに調べなおしているので、簡単に上げておきます。
できるだけ簡単に説明するために、WPFのプロジェクトを作成したときにデフォルトで作成される「MainWindow」をMVVM化していきます。

プロジェクトの作成

基本的に、「WPFアプリ(.NET Framework)」または「WPF App(.NET Core)」のどちらかで作成します。

ビュー

デフォルトで作成される「MainWindow.xaml」がビューを定義するファイルとなります。
こんな感じの中身になっているかと思います。


MainWindow.xaml
<Window x:Class="MVVM_Sample.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:MVVM_Sample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        
    </Grid>
</Window>


これをベースに、テキストボックスとボタンを追加して、ボタンを押すとテキストの内容が書き換わるようなものを作ってみます。
以下の様に修正して、テキストボックスとボタンを追加します。


MainWindow
<Window x:Class="MVVM_Sample.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:MVVM_Sample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="24"/>
            <RowDefinition Height="5"/>
            <RowDefinition Height="24"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="{Binding ViewText}"/>
        <Button Grid.Row="2" Width="74" HorizontalAlignment="Right" Content="変更" Click="ButtonClick"/>
    </Grid>
</Window>



ポイントは「TextBlock」タグの「Text」属性です。
文字列を表示したい場合はここに文字列を設定しますが、今回はビューモデルを介してやり取りしたいので「Binding ViewText」と設定しています。
これにより、ビューモデル側から「ViewText」プロパティで値を操作できるようになります。

ビューモデル

デフォルトでは作成されないので、適当な名前でクラスファイルを作成します。
今回は「MainWindow_VM.cs」と言う名前で作成していきます。
追加はソリューションエクスプローラーからプロジェクトを右クリックし、「追加」→「クラス」→「ファイル名入力」で追加することができます。
追加されると以下の様な中身になっているかと思います。


MainWindow_VM.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MVVM_Sample
{
    class MainWindow_VM
    {
    }
}



こいつをビューモデルで使用できるように改造していきます。 ポイントは…

  • 「System.ComponentModel」の参照を追加
  • 「INotifyPropertyChanged」インタフェースを実装
  • 「PropertyChangedEventHandler」イベントハンドラを実装
  • ビューの値を保持できるように、メンバ変数を追加
  • ビューとやり取りする用の、プロパティを追加

です。

それでは改造していきます。


MainWindow_VM.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel; //追加

namespace MVVM_Sample
{
    public class MainWindow_VM : INotifyPropertyChanged //インターフェースを実装
    {
        /// <summary>
        /// イベントハンドラを追加
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// ビューの値を保持するためのメンバ変数
        /// </summary>
        private string m_ViewText;

        /// <summary>
        /// デフォルトコンストラクタ
        /// </summary>
        public MainWindow_VM()
        {
            ViewText = "変更前!"; //初期値を設定
        }

        /// <summary>
        /// ビューとやり取りするためのプロパティ
        /// </summary>
        public string ViewText
        {
            get { return m_ViewText; }
            set
            {
                m_ViewText = value;
                OnPropertyChanged("ViewText"); //イベント発動
            }
        }

        /// <summary>
        /// プロパティ変更イベントハンドラ
        /// </summary>
        /// <param name="p_PropertyName">プロパティ名</param>
        public void OnPropertyChanged(String p_PropertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(p_PropertyName));
        }
    }
}


詳細は省略しますが…こんな感じです。

モデル