業務のためのC#・C言語・C++学習

主にC#の文法やWPF周りのアウトプットに利用してます。

【C#-WPF】MVVMパターンにおけるViewとViewModel間のインスタンス生成方法について

MVVMパターンにおけるViewとViewModel間のインスタンス生成方法は主に2つある。
・Viewのコンストラクタでインスタンスを生成する方法。
XAMLのWindow.DataContextにインスタンスを生成する方法である。

準備

WPFのプロジェクトを作成したら自動生成されるMainWindow.xamlと同じ階層にMainViewModel.csを追加する。

ViewModelの役割:MainViewModel.cs 
Viewの役割:MainWindow.xaml(MainWindow.xaml.cs)

MainViewModel.cs, MainWindow.xamlについて述べる。

ViewModel:MainViewModel.cs

MainWindow.xamlのTextBlockで利用するNameプロパティ値を設定。
RaisePropertyChangedはUI更新のためのお約束設定である。詳細は割愛。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;//for INotifyPropertyChanged

namespace DataContext
{
    public class MainViewModel : INotifyPropertyChanged
    {
        //UIに自動更新を行うためのイベント
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        //TextBlock用プロパティ
        public string name = "Nameの初期設定を表示";
        public string Name
        {
            get { return name; }
            set
            {
                if (name != value)
                {
                    name = value;
                    RaisePropertyChanged("Name");
                }
            }
        }
    }
}
View:MainWindow.xaml

TextBlockをNameをプロパティ値とし設定。

<Window x:Class="DataContext.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:DataContext"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock Text="{Binding Name}"/>
    </Grid>
</Window>

Viewのコンストラクタでインスタンスを生成する方法

MainWindow.xaml.cs

コンストラクタにおいてDataContextにMainViewModelのクラスを代入しインスタンス変数を生成する。これによりViewとViewModelを関連づける。

namespace DataContext
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainViewModel();
        }
    }
}

出力結果
MainViewModel.csで設定したTextBlock用プロパティがUIに正常に表示された。

XAMLのWindow.DataContextにインスタンスを生成する方法

XAMLにWindow.DataContextを追加しMainViewModelを指定。これによりViewとViewModelを関連づける。

<Window x:Class="DataContext.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:DataContext"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <TextBlock Text="{Binding Name}"/>
    </Grid>
</Window>

Window.DataContext内のlocalはXAML名前空間で指定した変数のことである。

   <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>

ここでlocalはxaml名前空間にあるように"clr-namespace:DataContext""部分に等しいという意味であり、clr-namespaceはプロジェクトがあるMainWindowやMainViewModelと同じ階層を意味しています。

 xmlns:local="clr-namespace:DataContext"

出力結果
出力結果はViewのコンストラクタでインスタンスを生成する方法と同じです。