WPF+ReactivePropertyでのViewModelの初期化処理


ViewModelのコンストラクタでデータベースとかWEBサービスにアクセスしたくない

コンストラクタであんまり重い処理を実行したくない。例外出ても嫌だ。ダイアログでIntaractinNotificationでパラメータもらってデータベースにアクセスしてモデルを更新するとか、コンストラクタ終わったあとなんじゃ?ってわけで。

View

Interaction.Triggers に Loadedイベントに反応するトリガーを記述する。

<Window>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Loaded">
                <i:InvokeCommandAction Command="{Binding LoadedCommand}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>

</Window>

ViewModel

Loaded イベントに反応するコマンドを記述して、イベント処理内でデータベース処理とかする


public class FooViewModel : BindableBase
{
    private FooModel _model {get; set;}
    public ReactiveCommand LoadedCommand { get; set; } = new ReactiveCommand();
    public ReactiveProperty<string> Name {get; set;}
    public FooViewModel
    {
        // イベントに反応する
        LoadedCommand.Subscribe(OnLoaded);
    }
    public void OnLoaded()
    {
        // ここでデータベース処理とか
        using(var db = new AppDbContext())
        {
            _model = db.Foos.FirstOrDefault();
        }
        Name = _model.ObserveProperty(x => x.Name).ToReactiveProperty();
        // プロパティ変更通知しないと新しいReactivePropertyが機能しない
        RaisePropertyChanged(null);
    }
}

Prismを使っているので BindableBaseを利用し、変更通知にRaisePropertyChangedを使う。
Prismでなければ INotifyPropertyChangedの実装を直接使ったり、他の方法を使う。

その他

RaisePropertyChanged(null) の代わりに RaisePropertyChanged() (引数なし)を使ってもViewは更新されない。何故だろう。