Help us understand the problem. What is going on with this article?

INotifyPropertyChanged実装のありえない面倒くささと、ReactivePropertyの信じられない素晴らしさ

期待

MVVMや双方向バインディングでは、バインドしたViewModelの更新を画面に反映して欲しいです。
そのような場合、ViewModelにINotifyPropertyChangedインターフェイスを実装して実現するようです。

INotifyPropertyChangedを実装する方法

方法 : INotifyPropertyChanged インターフェイスを実装するに、従って実装します。

ViewModel.cs
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfApplication1
{
    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private string message = "";
        public string Message
        {
            get
            {
                return this.message;
            }
            set
            {
                if (value != this.message)
                {
                    this.message = value;
                    NotifyPropertyChanged();
                }
            }
        }
    }
}

次のような気持ちでいっぱいです。

  • PropertyChangedEventHandlerとNotifyPropertyChangedのおまじない感
  • 自動実装プロパティーで、プロパティーを簡潔に書けるC#の魅力とはなんだったのか?
  • (必要な場合)さらにModelとの変換ロジックも実装するの?
  • こんなことで「ViewModelを書けば、(ビューの)データと描画ロジックを美しく分離できる」と言えるのか?
MainWindow.xaml.cs
using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var vm = new ViewModel();

            DataContext = vm; // DataContextにViewModelをバインド
            vm.Message = "Hello"; // DataContextのプロパティーを更新すると画面に反映
        }
    }
}
MainWindow.xaml
<Window x:Class="WpfApplication1.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:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock Text="{Binding Message}"/>
    </Grid>
</Window>

こちらは期待通りです。

スクリーンショット

実行すると、こんな感じです。
スクリーンショット 2015-10-20 22.34.20.png

軽減手段

いくつか多少軽減する方法はあるようです。

データクラスとして非本質的な記述が、あまり減らないのが気になります。

ReactivePropertyを使うと

ViewModel.cs
using Reactive.Bindings;

namespace WpfApplication1
{
    public class ViewModel
    {
        public ReactiveProperty<string> Message { get; } = new ReactiveProperty<string>();
    }
}

この簡潔さ。データクラスがプロパティー定義だけを持つ、圧倒的な簡潔さです。
型名は少し長いですが、VisualStudioの補完機能を考えれば気になりません。

MainWindow.xaml.cs
using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var vm = new ViewModel();

            DataContext = vm; // DataContextにViewModelをバインド
            vm.Message.Value = "Hello"; // DataContextのプロパティーを更新すると画面に反映
        }
    }
}
MainWindow.xaml
<Window x:Class="WpfApplication1.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:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock Text="{Binding Message.Value}"/>
    </Grid>
</Window>

値の参照・設定にValueを使う点に注意が必要です。
はじめて試した時、見事にはまりました。

リンク

ledsun
編集リクエスト、コメント大歓迎です。
luxiar
Ruby on Rails専門のWebアプリケーション開発に特化した町田の受託開発企業です
http://www.luxiar.com/index.html
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした