「C#][WPF]ロードに時間がかかる際の非同期待ちあわせのやりかた


すぐに忘れてしまうのでメモ。

ViewModelのロジック側はさくっと非同期呼び出しをします。そのとき、ViewModelに待ち状態のフラグ(例だとIsWaiting)を持っておきます。

  this.IsWaiting = true;
  var action = new Action(Hoge);
  action.BeginInvoke(ar => { action.EndInvoke(ar); this.IsWaiting = false; }, null);

画面ロード時に表示するビジーアニメーションはDomain Parked With VentraIP Australiaからお借りしました。共通Resourceにしておくと便利ですね。

使うときはGridでレイアウトします。GridのRow、Columnを同じ番号にするとコントロールが重なるので、既存のコントロールの上にビジーアニメーションコントロールを重ねて使います。ActualWidth、ActualHeightでいっぱいに広げるといいのですが、重ねる元がAuto指定の場合、タイミングによっては値が確定する前にアクセスされてしまい、無限に広がってしまうので注意しないといけませんでした(うまくいくタイミングはよくわかってませんが……)。

<Grid>
  <StackPanel Name="target">ここにかさねる</StackPanel>
  <Control Visibility="{Binding IsWaiting, Converter={StaticResource BooleanToVisibilityConverter}}"
           Width="{Binding Path=ActualWidth, ElementName=target}" 
           Style="{StaticResource BusyAnimationStyle}"
           Background="Transparent"
   />
</Grid>

こんなかんじ。あ、BooleanToVisibilityConverterをStaticResourceに入れといてください。