LoginSignup
2
7

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

Last updated at Posted at 2020-09-06

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は更新されない。何故だろう。

2
7
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
7