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