今回のテーマは「通知領域(タスクトレイ)」です。アプリをバックグラウンドで実行させ、ユーザに通知を送る機能を実装します。
この記事では以下の内容を説明します。
- NotifyIconコントロールの基本的な使い方
- コンテキストメニューの作成
- 通知バルーンの表示方法
- フォームの最小化とバックグラウンド実行
次のような方に役立つ内容となっています。
- 常駐アプリを作りたい方
- ユーザに通知を送る機能を実装したい方
実践入門編(2)、(3)、(4)でポモドーロタイマーを作り、複数フォームの扱い方とモーダル/モードレスについて学びました。
今回は、このタイマーアプリを通知領域へ対応させ、バックグラウンドで実行できるアプリへとレベルアップさせます。
通知領域は「バックグラウンドで動くアプリとユーザをつなぐインターフェイス」として役立ちます!
演習のコード一式はGitHubに置いてあります。
YouTubeの動画は以下です。
講義:通知領域(タスクトレイ)の概念と基本要素
通知領域とは
通知領域(タスクトレイ、システムトレイとも呼ばれる)は、Windowsの画面下にある「タスクバー」の右側にあるアイコン群の表示エリアです。

通知領域の主な目的は以下の通りです。
- 常駐アプリケーションの表示場所:常にバックグラウンドで動作するアプリの存在をユーザに示す
- システム通知の提供:重要なイベントや状態変化をユーザに知らせる
- 簡易アクセス:頻繁に使用するツールや機能に素早くアクセスできる
実際のアプリ開発では、以下のようなケースで通知領域が有効です。
- バックグラウンド処理を行うユーティリティアプリ
(スケジューラ、モニタリングツールなど) - 常に準備状態にあるべきコミュニケーションツール
(チャットアプリなど) - ユーザに通知を送る必要があるアプリ
(タイマーのアラーム、リマインダーなど)
「通知領域」ってWindowsの右下に表示されるアイコンエリアのことなんだね。
普段何気なく使っていたけど、アプリ開発側から見ると重要な機能なんだ!
前回お話したWebアプリ連携(WebView2)と通知領域との組み合わせも有用です。
Webシステムからの通知をWindowsデスクトップへ直接表示したいといったユースケースで便利です。
Webアプリ連携(WebView2)についての記事は以下です。

NotifyIconコントロール
WinFormsで通知領域機能を実装するための中心となるのが「NotifyIcon」コントロールです。
NotifyIconコントロールの主な特徴は以下です。
- 非視覚的コントロール
- 通知領域でアプリアイコン表示
- イベント処理とコンテキストメニュー表示
- バルーン通知機能
①非視覚的コントロール
NotifyIconコントロールは画面に直接表示されないコントロールです。
通知領域に表示されるアイコンとその動作を制御するための仕組みと考えるとよいでしょう。

Timerコントロールと同じで、フォーム上で見えないけど裏で仕事をしてくれるってことだね!
②通知領域でアプリアイコン表示
通知領域にアプリのアイコンを表示することで、アプリがバックグラウンドで実行中であることをユーザに示します。
アイコンは通常、アプリの状態を表すデザインにします。
③イベント処理とコンテキストメニュー表示
通知領域のアイコンはユーザの操作(クリック、ダブルクリックなど)に反応できます。例えば以下を行います。
- クリック/ダブルクリック:一般的にはアプリのメイン画面を表示する
- マウスオーバー:ツールチップでアプリの状態などの情報を表示
- 右クリック:コンテキストメニューを表示
コンテキストメニューは右クリックした際に表示されるメニューです。アプリの基本機能へ素早くアクセスすることを可能にします。以下はサウンドの例です。

④バルーン通知機能
バルーン通知は、通知領域のアイコンから一時的に表示されるメッセージボックスです。以下のような特徴があります。
- 一時的な表示:数秒間表示された後、自動的に消える
- 非侵入的な(控えめな)通知:ユーザの作業を中断せずに情報を伝える
- 情報レベルの設定:情報、警告、エラーなど、異なるアイコンで通知の重要度を示せる
以下はバルーン通知の例です。

バックグラウンド実行の考え方
WinFormsアプリを通知領域と組み合わせてバックグラウンドで実行させる際の基本的な考え方は以下の通りです。
フォームの「閉じる」と「アプリの終了」を分離
通常、フォームの閉じるボタン(×)をクリックすると、アプリは終了します。
しかし、通知領域を使ったアプリでは、フォームを閉じてもアプリ自体は終了せず、バックグラウンドで動作し続けるようにします。
ユーザへの通知とインタラクション
ユーザインターフェース(フォーム)が表示されていない状態でも、以下の方法でユーザとのインタラクションを維持します。
- バルーン通知を使用して重要なイベントを通知
- 通知領域アイコンのツールチップを動的に更新して状態を表示
- アイコンをクリックした際にフォームを再表示する機能を提供
通知領域を使ってるアプリって、確かにこういう動作をするかも!
演習でタイマーアプリを通知領域へ対応させ、理解を深めましょう!
演習:タイマーアプリを通知領域へ対応させる
今回作るアプリと作成手順
以下で作成したポモドーロタイマーアプリを拡張します。

時間を選択して設定し動作させられる簡単なタイマーアプリでしたね。

これに以下の機能を追加します。
- フォームを閉じてもバックグラウンドで動作し続ける
- タイマー残り時間を通知領域アイコンのツールチップに表示
- タイマー完了時にバルーン通知を表示
- 通知領域アイコンのコンテキストメニューから操作可能
ユーザの作業を邪魔せずバックグラウンドで動作して、時間になったら通知してくれるようになるね!
以下の手順で進めます。
- 手順1:NotifyIconコントロールの追加と設定
- 手順2:通知領域アイコンを活用する機能を実装
手順1:NotifyIconコントロールの追加と設定
Form1.csをデザイナで開き、ツールボックスから「NotifyIcon」コントロールを探して、フォームへ追加します。
NotifyIconのプロパティはデフォルト値のままでよいです。
(以降、Nameは「notifyIcon1」となっていると想定して説明します)
NotifyIconの基本設定を行うメソッド(SetupNotifyIcon)をForm1.csへ追加します。
// ★NotifyIconの基本設定を行う
private void SetupNotifyIcon()
{
// 基本プロパティの設定
notifyIcon1.Icon = SystemIcons.Application;
notifyIcon1.Text = "ポモドーロタイマー";
// ウィンドウを表示するデリゲートをローカルで宣言
Action showMainWindow = () => {
this.Show();
this.WindowState = FormWindowState.Normal;
};
// イベントをラムダ式で設定
notifyIcon1.DoubleClick += (s, e) => showMainWindow();
// コンテキストメニューの作成
var menu = new ContextMenuStrip();
// 表示メニュー項目の追加
var showItem = new ToolStripMenuItem("表示");
showItem.Click += (s, e) => showMainWindow();
menu.Items.Add(showItem);
// 終了メニュー項目の追加
var exitItem = new ToolStripMenuItem("終了");
exitItem.Click += (s, e) => {
Application.Exit();
};
menu.Items.Add(exitItem);
// メニューをNotifyIconに設定
notifyIcon1.ContextMenuStrip = menu;
}
今回、プロパティやイベントの設定をコード上で行っています。
WinFormsのコントロールはデザイナ上/コード上という二通りの設定方法があるのです。
イベントの記述にはラムダ式を使い、簡潔に記述しています。ラムダ式の使い方の詳細は以下も参考にしてください。

作成したSetupNotifyIconメソッドをForm1のコンストラクタから呼び出すように追加します。
public Form1()
{
InitializeComponent();
SetupNotifyIcon(); //★追加
_remainingSeconds = _workMinutes * SecondsPerMinute;
}
手順2:通知領域アイコンを活用する機能を実装
次に、通知領域のアイコンを活用する機能を実装します。
フォームを閉じた時の処理(バックグラウンド実行)
通常、フォームの閉じるボタン(×)をクリックするとアプリが終了しますね。
通知領域を活用したアプリでは、アプリを終了させる代わりにフォームを非表示にし、バックグラウンドで実行し続けるようにします。
Form1.csへ以下のメソッドを追加します。
//★アプリを終了させる代わりにフォームを非表示
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true; // フォームを閉じるのをキャンセル
this.Hide(); // 代わりに非表示にする
//バルーン通知
notifyIcon1.ShowBalloonTip(
1000,
"ポモドーロタイマー",
"タイマーはバックグラウンドで実行中です",
ToolTipIcon.Info);
}
//元のOnFormClosingを呼び出す
base.OnFormClosing(e);
}
ここでは、ポリモーフィズムの仕組みを使ってForm1の親クラスであるFormのOnFormClosingをカスタマイズしています。
オブジェクト指向・ポリモーフィズムの基礎から復習したい場合は以下を参考にしてください。

タイマー完了時のバルーン通知
タイマーが完了したときに、メッセージボックスではなくバルーン通知を表示するようにtimer1_Tick
メソッドを修正します。
private void timer1_Tick(object sender, EventArgs e)
{
_remainingSeconds--;
if (_remainingSeconds < 0)
{
timer1.Stop();
notifyIcon1.ShowBalloonTip(2000, "ポモドーロタイマー", "時間になりました!", ToolTipIcon.Info);
ResetTimer();
return;
}
UpdateDisplay();
}
通知領域アイコンのツールチップに残り時間を表示
タイマーの残り時間を、フォーム上の表示と同時に通知領域アイコンのツールチップテキストにも反映させるために、UpdateDisplay
メソッドを修正します。
private void UpdateDisplay()
{
int minutes = _remainingSeconds / SecondsPerMinute;
int seconds = _remainingSeconds % SecondsPerMinute;
string time = $"{minutes:00}:{seconds:00}";
labelTime.Text = time;
notifyIcon1.Text = time; // タスクトレイアイコンのツールチップにも表示
}
これで完成です!動かしてみましょう。
完成したForm1.csはGitHubにあります。
アプリを実行
事前確認
アプリを実行する前に、Windowsの「設定>システム>通知」でアプリ通知機能がONになっていることを確認しましょう。

個別のアプリについての設定もあります。アプリは一度実行するとここに表示されるようになります。こちらもONになっていることを確認しましょう。

実行
実行すると次のように、「x」ボタンで通知領域へ格納し、時間がくるとバルーン通知でお知らせしてくれます。

これで、作業に集中できるバックグラウンド実行型のポモドーロタイマーができたね!
まとめ
本記事では、WinFormsアプリ開発における通知領域機能の実装について学びました。
通知領域を使ったアプリには以下の特徴と利点があります:
- バックグラウンド実行:フォームを閉じてもアプリが動作し続けるため、常駐型アプリを実現できる
- 非侵入的な通知:バルーン通知により、ユーザの作業を中断せずに情報を伝えられる
- 簡易アクセス:通知領域アイコンとコンテキストメニューにより、アプリの主要機能に素早くアクセスできる
WinFormsではNotifyIconコントロールを使うことで実現できます。
タイマーアプリの演習を通じて、通知領域を使った機能を実際のアプリへ統合する方法を学びました。
フォームを閉じてもバックグラウンドで動作し続け、タイマー完了時にはユーザに通知を送るというような機能は、実用的な開発する上でも重要な要素となります。
引き続き、一緒にC# WinFormsアプリ開発を学んでいきましょう!