ReactivePropertyを導入すると、オブザーバーベースのプログラミングが可能になります。
従来のWPFのプログラミングでは、イベントをきっかけに処理を行う
イベントドリブン型(データバインディングも含む)の設計が基本になります。
一方、ReactivePropertyでは
「どのタイミングで誰がデータを書き換えたか」
ではなく、
「データが変更された」という事実
に注目して処理を組み立てます。
これは従来のイベント中心の設計とは異なる、
オブザーバーベースのプログラミングパラダイムと言えるでしょう。
このようにReactivePropertyは、導入する価値が非常に高い仕組みですが、
WPFで利用する場合には、さらにいくつかのメリットがあります。
まず、データバインディング用のプロパティを実装する際に必要となる
ボイラープレートコードを大幅に省略することができます。
また、コマンドをバインディングするために通常は ICommand を実装する必要がありますが、
ReactivePropertyでは ReactiveCommand を使用することで、
この部分も簡潔に記述することが出来ます。
そのため、ViewModelのコード量を減らすことができ、
全体的にコーディングが楽になります。
従来型のMVVM
RelayCommand.cs(ICommandの実装)
using System;
using System.Windows.Input;
public class RelayCommand : ICommand
{
private readonly Action _execute;
public RelayCommand(Action execute)
{
_execute = execute;
}
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter) => true;
public void Execute(object? parameter)
{
_execute();
}
}
ViewModel
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
public class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private string _name = "";
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
public ICommand ShowCommand { get; }
public MainWindowViewModel()
{
ShowCommand = new RelayCommand(Show);
}
private void Show()
{
MessageBox.Show(Name);
}
void OnPropertyChanged([CallerMemberName] string? name = null)
{
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(name));
}
}
XAML(UI)
<StackPanel Margin="20">
<TextBox Width="200"
Text="{Binding Name,
UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="表示"
Command="{Binding ShowCommand}"
Width="100"/>
</StackPanel>
ReactiveProperty版
ReactivePropertyを使うとかなり短くなります。
ViewModel
using Reactive.Bindings;
using System.Windows;
public class MainWindowViewModel
{
public ReactivePropertySlim<string> Name { get; }
= new("");
public ReactiveCommandSlim ShowCommand { get; }
public MainWindowViewModel()
{
ShowCommand = new ReactiveCommandSlim();
ShowCommand.Subscribe(_ =>
{
MessageBox.Show(Name.Value);
});
}
}
省略していますが、INotifyPropertyChangedとIDisposableを実装した方がよいです。
XAML
<StackPanel Margin="20">
<TextBox Width="200"
Text="{Binding Name.Value,
UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="表示"
Command="{Binding ShowCommand}"
Width="100"/>
</StackPanel>
RelayCommandが綺麗に消えて、
プロパティのボイラープレートも
private string _name = "";
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
から
public ReactivePropertySlim Name { get; }
= new("");
へと、大分すっきりした形になりました。
WPFでプログラムを書く場合、データバインディングのための
プロパティを大量に定義することになります。
そのため、このようにシンプルなコードで実装できる点は非常にありがたいところです。

コメント