「処理中ですよ」のプログレスリングダイアログを出して、勝手に閉じさせる方法

記事概要

UWPにおいて、時間のかかる処理開始後、プログレスリング(「処理中ですよ」を表す、くるくる回るアニメーション)をダイアログとして既存の画面の上に重ねて表示し、処理完了後には自動で閉じさせる方法について。
 

f:id:Tiratom:20190317230454p:plain
こんな表示を画面の上に表示させて、処理後は勝手に消したいです。

 
※ダイアログとは: ダイアログ コントロール | Microsoft Docs
プログレスリングとは: プログレス コントロールのガイドライン | Microsoft Docs

 

実現したいこと概要

まず、実現したいことに関する処理の流れについてです。
① データの登録ボタンクリック
② データの登録処理が開始される
③ 画面上に、処理中ダイアログ(ダイアログ上にプログレスリングも表示させる)が表示される
④ データの登録処理が進む
⑤ データの登録処理が完了する
⑥ 処理中ダイアログを(ユーザー操作ではなく)コードから閉じる

という流れを考えています。  
 

実現方法の流れ 

まず、ダイアログとして表示させる用のXAMLを用意します。
続いて、実際の画面用のXAMLをいじります。
最後に、コードビハインドをいじります。
 
 

1.ダイアログとして表示させる用のXAMLを用意する

(1) ソリューションエクスプローラーにおいて、どこか適当な場所で右クリックをします。

(2) 追加>新しい項目の追加>VisualC#>コンテンツダイアログ を選んで、xamlファイルを作成します。
今回仮名称として「RegisterProgressDialog」という名前にしました。

(3) 作成したファイルを編集します。
以下のような感じで作成しました。

<ContentDialog
    x:Class="XXXXX.RegisterProgressDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="処理中ですよ"
    mc:Ignorable="d">

    <Grid>
        <ProgressRing
            Width="50"
            Height="50"
            HorizontalAlignment="Center"
            IsActive="True" />
    </Grid>
</ContentDialog>

 
ユーザーにダイアログのボタン操作はさせないので、デフォルトで用意してある

IsPrimaryButtonEnabled="True"
                       IsSecondaryButtonEnabled="True"
                       PrimaryButtonText="OK"
                       SecondaryButtonText="Cancel"

のプロパティについては削除しています。

 

2.実際の画面用のXAMLをいじる

ButtonのClickアクションとしてコードビハインドにおいて、データ登録用メソッド(仮称として"RegisterData"メソッドとしておきます)を設定しておきます。

<Button
    Click="{x:Bind 【RegisterDataメソッド】}"
    Content="登録"/>

※環境によってメソッドの指定方法も異なると思うので、【】内は適宜変えてください

 

3.コードビハインドをいじる

3-1.ダイアログを表示させる処理の記述

RegisterDataメソッド内において、処理の先頭に

var progressDialog = new RegisterProgressDialog();
var showingDialog = progressDialog.ShowAsync();

を書きます。
 
1行目では、先ほど2で作成したダイアログXAMLを読み込んでいます。
2行目では、1行目で読み込んだダイアログを実際のUWPの画面に表示させます。
ここでawait progressDialog.ShowAsync(); としていないのは、そうやって書いてしまうと画面の操作を待ち続けて先に進まなくなってしまうからです。
 

3-2. データ登録メソッドの記述

そのあとは、データ登録メソッドを記述します。
ここのソースコードは割愛します。
 

3-3. ダイアログを閉じる処理の記述

RegisterDataメソッドの末尾に、以下を記述します。

showingDialog.Cancel();
progressDialog.Hide();

 
1行目では、ダイアログの待機処理を終了させます。(僕の試した限りでは、これを書かなくても問題なく動作したので、なぜ必要なのかがよくわかっておりません…。)

2行目では、ダイアログを閉じます。

 
これで実際に動かしてみれば、想定通り処理開始→プログレスリングが画面上に表示→処理終了後、プログレスリングが消える となっているはずです。

 

補足

なんだかまどろっこしい書き方をしているのかもしれませんが、ちょっと以下のような理由がありこういう書き方になっています。
・MVVMモデルにあこがれており、XAMLのコードビハインドを、XAML付属のCSファイルではなく、別のファイルに分けていたため、その別ファイル内において、this.【ダイアログ】.ShowAsync() に該当する処理を書く方法がよくわからなかった
・ProgressRingをダイアログに追加する方法として、XAMLで記述する方法しかわからなかった(CSファイル上でProgressRingをContentDialog上に載せる方法がわからなかった)

 

参考サイト