Windows GUIプログラミング入門14 処理中表示

# ■はじめに
前回のプログラムは大きなCSVを読み込むと、読み込み完了までの間、画面が固まってしまいます。
そこで今回はその対策をします。

キーワード：TaskbarItemInfo, async, await, ドキュメントアウトライン

[注意]
これまでの回で説明済みの操作方法等は、説明を省略したり簡略化している場合があります。

# ■開発環境
* Windows 10 (バージョン1703)
* Visual Studio Community 2017
* .NET Framework 4.x

# ■作ってみる

## ◇処理中テキスト

ドキュメントアウトラインで`listView`の目のアイコンをクリックしてリストビューを非表示にします。

![wbg14-02.png](https://qiita-image-store.s3.amazonaws.com/0/142879/35434cec-b37f-76e5-1619-7cfcbae12124.png)


`TextBlock`をリストビューのあったグリッド行（Row=1）に配置します。

![wbg14-03.png](https://qiita-image-store.s3.amazonaws.com/0/142879/676a6045-668f-2e8d-d317-16196b5f9027.png)


`TextBlock`を右クリック、「レイアウト」 - 「すべてリセット」し、
`x:Name`を`loadingText`にし、
プロパティの
「レイアウト」 - `HorizontalAlignment`と`VerticalAlignment`を`Center`に、
「テキスト」の`FontSize`を`48 px`に、
「共通」の`Text`を`読み込み中・・・`に設定します。

![wbg14-04.png](https://qiita-image-store.s3.amazonaws.com/0/142879/bfc63c27-6c15-ec52-3df7-622bb30e7df4.png)


`TextBlock`のプロパティ「外観」の`Visibility`を`Collapsed`にして非表示にします。

`TextBlock`の設定が終わったので、ドキュメントアウトラインで`listView`の非表示を解除しておきます。

ここまでで`TextBlock`の定義は以下のようになっています。

```Xml
<TextBlock x:Name="loadingText" Grid.Row="1" TextWrapping="Wrap" Text="読み込み中・・・" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Visibility="Collapsed"/>
```

## ◇処理中タスクバー

`MainWindow`にタスクバーの処理中表示用の定義を追加します。

```Xml
<Window.TaskbarItemInfo>
    <TaskbarItemInfo x:Name="taskbarInfo"/>
</Window.TaskbarItemInfo>
```

![wbg14-10.png](https://qiita-image-store.s3.amazonaws.com/0/142879/e7fabc93-b17c-1067-a3a0-c0bb429cfac6.png)


## ◇ロジック

コンストラクタに以下の処理を追加します。

```CSharp
// 複数のスレッドからのアクセスを有効化
BindingOperations.EnableCollectionSynchronization(this.ZipRecords, new object());
```

以下のメソッドを追加します。

```CSharp
/// <summary>
/// データ読み込み中の画面表示
/// </summary>
/// <param name="loading">データ読み込み中の時にtrue, 読み込み終わったらfalseを設定する</param>
private void SetLoadingUI(bool loading)
{
    if (loading)
    {
        // 処理中

        // 画面全体を無効化
        this.IsEnabled = !loading;
        // 処理中メッセージを表示
        loadingText.Visibility = Visibility.Visible;
        // リストを隠す
        listView.Visibility = Visibility.Collapsed;
        // タスクバーアイコンを処理中表示にする
        taskbarInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Indeterminate;
    }
    else
    {
        // 処理終り

        // 画面全体を有効化
        this.IsEnabled = !loading;
        // 処理中メッセージを隠す
        loadingText.Visibility = Visibility.Collapsed;
        // リストを表示
        listView.Visibility = Visibility.Visible;
        // タスクバーアイコンを通常に戻す
        taskbarInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
    }
}
```

```CSharp
/// <summary>
/// CSVファイル読み込みタスク
/// </summary>
/// <param name="filePath">CSVファイルパス</param>
/// <returns></returns>
private Task ReadCsvTask(string filePath)
{
    return Task.Run(() => { ReadCsv(filePath); });
}
```

`openMenu_Click`メソッドを修正します。

```CSharp:メソッド定義（修正前）
private void openMenu_Click
```

```CSharp:メソッド定義（修正後）
private async void openMenu_Click
```

```CSharp:CSV読み込み処理（修正前）
this.IsEnabled = false;

// CSV読み込み
ReadCsv(dlg.FileName);

this.IsEnabled = true;
```

```CSharp:CSV読み込み処理（修正後）
SetLoadingUI(true);

// CSV読み込み
await ReadCsvTask(dlg.FileName);

SetLoadingUI(false);
```

処理の流れは、`await`を付けた`ReadCsvTask`メソッドが呼び出されたら`openMenu_Click`メソッドを一旦抜けます（他に並行して動いている処理があればそちらをやります）。
そして、`ReadCsvTask`メソッドが終了したらその下の処理が実行されます。

ここでは、重たい処理（`ReadCsvTask`）を実行する直前に画面を処理中表示にし、重たい処理が終わったら処理中表示を元に戻しています。
![wbg14-30.png](https://qiita-image-store.s3.amazonaws.com/0/142879/32a2db43-2619-4ac1-e3c3-a0346e8eef17.png)

# ■動かしてみる
実行してみます。
一番大きい、全国一括データを読み込ませてみます。
![wbg14-20.png](https://qiita-image-store.s3.amazonaws.com/0/142879/dbf77441-a999-8889-6ae3-17ed692a1b37.png)

タスクバーの表示が、
![wbg14-21.png](https://qiita-image-store.s3.amazonaws.com/0/142879/92103881-2ce7-0738-1497-7f1afda3efbf.png)

↓

処理中に変わり、
![wbg14-23.png](https://qiita-image-store.s3.amazonaws.com/0/142879/76ea0769-2c91-bd8f-2d85-c46e45f7ffa9.png)

リストビューが隠れて代わりに処理中のテキストが表示されます。
前回と違って、読み込み中でもウィンドウを移動したりサイズ変更したりできます。
![wbg14-22.png](https://qiita-image-store.s3.amazonaws.com/0/142879/fdffbec2-57bb-5ac6-12a7-ae3fbb226c33.png)

読み込みが終わるとリストビューが表示されます。
![wbg14-25.png](https://qiita-image-store.s3.amazonaws.com/0/142879/16eac9fe-6bc8-2a23-0979-5f7176b20d93.png)

おしまい

---

# ■参考サイト

* [TaskbarItemInfo クラス - MSDN](https://msdn.microsoft.com/ja-jp/library/system.windows.shell.taskbariteminfo.aspx)

---

[＜＜ 最初の記事](http://qiita.com/Kosen-amai/items/f9e3df2aa80363f5af5b "Windows GUIプログラミング入門1 メッセージボックス表示") 　 [＜ 前の記事](http://qiita.com/Kosen-amai/items/b07b9d7c905efdbaf6d7 "Windows GUIプログラミング入門13 リストビュー(2)、メニュー") 　 [次の記事 ＞](http://qiita.com/Kosen-amai/items/44392fdf3bd8b56cfacb "Windows GUIプログラミング入門15 インストーラー(1)")