nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

INotifyPropertyChangedを使った簡単なWPFサンプル例 (MVVMパターンに修正)

サンプル説明

前回のコードをMVVMに直します。アプリ表示は、同一になります。

プロジェクト構成では、前回と比較して、ViewModel.csファイルを追加しました。

コード修正が入るファイルは、MainWindow.xaml.csファイルとMainWindow.xamlです。

前回と比較して、データコンテキストに設定するのは、Personクラスのインスタンスではなく、ViewModelクラスのインスタンスとなります。 また、xaml側で、データコンテキストを設定しています。

以下のサイトを参考にさせていただきました。 garafu.blogspot.jp

プロジェクト構成とアプリ表示

  • プロジェクト構成
    f:id:nprogram:20180104155018p:plain

  • アプリ表示
    f:id:nprogram:20180104150605p:plain

コード

[ViewModel.cs]

namespace WpfApp1
{
    public class ViewModel
    {
        public Person Person { get; set; }

        public ViewModel()
        {
            this.Person = new Person();

            this.Person.Name = "Tom";
        }
    }
}

[MainWindow.xaml]

<Window x:Class="WpfApp1.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:WpfApp1"
        xmlns:vm="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="167.828" Width="443.238">
    <Window.DataContext>
        <vm:ViewModel />
    </Window.DataContext>
    <TextBlock Text="{Binding Person.Name}"/>
</Window>

[MainWindow.xaml.cs]

using System.Windows;

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {   
        }
    }
}

[BindableBase.cs]

using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfApp1
{
    public class BindableBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null) =>
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

        protected virtual bool SetProperty<T>(ref T field, T value, [CallerMemberName]string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) { return false; }
            field = value;
            this.OnPropertyChanged(propertyName);
            return true;
        }
    }
}

[Person.cs]

namespace WpfApp1
{
    public class Person : BindableBase
    {
        private string name;

        public string Name
        {
            get { return this.name; }
            set { this.SetProperty(ref this.name, value); }
        }
    }
}

次回は

Viewで起きたイベントをViewModelに伝える手段として、ICommandインタフェースがあるので、次はこれについて記載予定