デスクトップアプリでは、「保存に失敗した」「ネットワーク接続が切れた」「バックアップが完了した」といった状態をユーザーへ伝える場面が頻繁にあります。こうした通知をすべてダイアログで表示すると、そのたびに操作を止めることになり、使い勝手を損ねます。
WinUI 3には、このような「知らせる必要はあるが、必ずしも操作を止める必要はない」メッセージに向いたInfoBarがあります。今回は単にInfoBarの書き方を紹介するのではなく、ContentDialogとの使い分け、Severityの意味、閉じさせるべき通知と閉じさせない通知、実務で扱いやすい実装方法まで整理します。
なぜInfoBarが必要なのか
通知UIを自作すると、背景色、アイコン、閉じるボタン、アクセシビリティ、ダークテーマへの対応などを個別に考える必要があります。また、重要度の違うメッセージを同じ見た目で表示すると、「これはエラーなのか、単なる案内なのか」が分かりにくくなります。
InfoBarは、アプリの状態変化を目立たせつつ、ユーザーの作業を不必要に中断しないためのインライン通知です。画面の上に浮かぶオーバーレイではなく、通常のレイアウト要素として配置されるため、表示するとそのぶん周囲のコンテンツが押し下げられます。Microsoftは、インターネット接続の喪失、自動保存の失敗、バックアップ完了、更新適用などを利用例として挙げています。
まずは最小構成を作る
次の例では、ネットワーク接続エラーを画面上部へ表示します。InfoBarは既定では閉じているため、表示したいタイミングでIsOpenをtrueにします。
<Grid RowDefinitions="Auto,*">
<InfoBar x:Name="StatusInfoBar"
Grid.Row="0"
Title="ネットワークに接続できません"
Message="接続状態を確認してください。"
Severity="Error"
IsClosable="False" />
<Grid Grid.Row="1" Padding="24">
<TextBlock Text="メインコンテンツ" />
</Grid>
</Grid>
C#側では、アプリが検出した状態に合わせて表示・非表示を切り替えます。
private void ShowNetworkError()
{
StatusInfoBar.Severity = InfoBarSeverity.Error;
StatusInfoBar.Title = "ネットワークに接続できません";
StatusInfoBar.Message = "接続状態を確認してください。";
StatusInfoBar.IsClosable = false;
StatusInfoBar.IsOpen = true;
}
private void HideNetworkError()
{
StatusInfoBar.IsOpen = false;
}
IsOpenはInfoBarの表示状態、Severityは通知の意味、IsClosableはユーザーが閉じるボタンで通知を消せるかを表します。ネットワーク切断のように「問題が解決するまで状態そのものが残っている」通知では、ユーザーが見た目だけ消してしまうより、接続復旧時にアプリ側から閉じる設計が分かりやすいでしょう。
Severityは「色」ではなく「意味」で選ぶ
InfoBarには、一般情報、Success、Warning、Errorといった重要度があります。ここで注意したいのは、Severityを単なる色指定として使わないことです。Microsoftのガイドでは、Errorは発生済みの問題、Warningは将来問題につながる可能性がある状態、Successは長時間処理やバックグラウンド処理の完了、既定のInformationalは注意してほしい一般情報という考え方が示されています。
たとえば「同期が完了しました」はSuccessが自然ですが、「あと3日で証明書が期限切れになります」はWarningです。「赤いほうが目立つから」という理由でErrorにすると、UI全体の意味が崩れます。また、色やアイコンだけに意味を持たせず、TitleやMessageにも状態を文章で書くことがアクセシビリティ上重要です。
ContentDialogとの使い分け
InfoBarとContentDialogの違いは、「ユーザーの作業を止める必要があるか」で考えると整理しやすくなります。
たとえばバックアップ完了、更新のお知らせ、ネットワーク切断のように、通知を見せながら別の操作を続けられるならInfoBarが向いています。一方、「この操作を続けるとデータが失われます。続行しますか?」のように、ユーザーが判断するまで先へ進ませたくない場合はContentDialogの役目です。特定のUI要素について一時的に説明するならFlyout、短い操作ガイドならTeachingTipが適しています。
つまり、すべての通知をInfoBarへ置き換えるのではなく、「状態通知なのか」「意思決定なのか」「その場限りの説明なのか」でコントロールを選ぶことが大切です。
ActionButtonを使って次の行動につなげる
状態を知らせるだけでなく、ユーザーに次の操作を提示したい場合はActionButtonを使えます。たとえば更新プログラムを検出したときに、詳細画面へ移動するボタンを置けます。
<InfoBar x:Name="UpdateInfoBar"
Title="更新プログラムがあります"
Message="新しいバージョンを利用できます。"
Severity="Informational">
<InfoBar.ActionButton>
<Button Content="詳細を見る"
Click="OpenUpdatePage_Click" />
</InfoBar.ActionButton>
</InfoBar>
通知とアクションを近くに置けるため、「知らせる」だけで終わらず、「では何をすればよいか」までUIで案内できます。ただし、重要な確認をActionButtonだけで済ませるのは避け、ユーザーの明示的な判断が必要な処理ではContentDialogなどを検討します。
実務ではInfoBarを画面ごとに乱立させない
複数ページを持つ業務アプリでは、各PageにInfoBarを置くより、NavigationViewとFrameを持つアプリのシェル側に共通InfoBarを置く設計が便利な場合があります。MicrosoftのモダンWinUI 3アプリ構成例でも、InfoBarをNavigationView内かつFrameより上に配置し、どのページを表示していても状態通知を見せられる構成が紹介されています。
たとえば通信障害、ライセンス期限、バックグラウンド同期失敗など、アプリ全体に影響する状態はMainWindow側のInfoBarへ集約し、ページ固有の入力エラーは各ページのUIで示す、と責務を分けると通知設計が整理しやすくなります。
注意点1:短時間に開閉を繰り返さない
InfoBarは長めに表示する状態通知を想定しています。Microsoftは、状態変化に応じて自動表示する場合、短時間に何度も表示・非表示を繰り返さないよう推奨しています。レイアウト内の要素なので、開閉のたびに下のコンテンツ位置が変わり、画面が落ち着かなくなるためです。
ネットワーク状態のように瞬間的な変動が起こり得る値をそのままIsOpenへ結び付ける場合は、一定時間状態が継続したときだけ表示するなど、アプリ側で揺れを吸収する設計も検討できます。
注意点2:開いたまま内容を変更するとき
InfoBarを開いたままTitle、Message、Severityなどを変更しても、その変更自体ではスクリーンリーダー向けの通知イベントが発生しないとMicrosoftは説明しています。支援技術の利用者にも更新を明確に伝える必要がある場合は、いったん閉じてから再度開く方法が推奨されています。
また、独自の背景色やアイコンを設定することもできますが、標準Severityの色はテーマ変更、高コントラスト、色覚への配慮などを考慮して設計されています。ブランドカラーへ安易に置き換えるより、まず標準スタイルを使うほうが安全です。
まとめ
InfoBarは「通知を表示する部品」というより、ユーザーの作業を止めずにアプリの状態を伝えるための仕組みとして捉えると使いどころが見えてきます。IsOpenで表示状態を管理し、Severityを意味に合わせて選び、必要ならIsClosableやActionButtonでユーザーの行動を設計します。
重要なのは、何でもInfoBarにすることではありません。操作を止める必要があるならContentDialog、特定箇所の一時的な説明ならFlyoutやTeachingTipを選びます。通知の見た目ではなく「ユーザーに何をしてほしいのか」からコントロールを選ぶと、WinUI 3アプリのUIはずっと整理しやすくなります。
参考資料
- Microsoft Learn – InfoBar
- Microsoft Learn – Structure a modern WinUI 3 desktop app
- Microsoft Learn – WinUI 3
コメント