WPFでの常駐アプリの作り方
WPFでは、タスクトレイの機能を使うためのAPIは用意されていません。
そのため、FormsのAPIを使って実装する必要があります。
概要
Pro WPF を参考に、タスクトレイ関連の機能をコンポーネントクラスでラップして、WPF側からつかっています。
- 作者: Matthew MacDonald
- 出版社/メーカー: Apress
- 発売日: 2010/04/30
- メディア: ペーパーバック
- 購入: 5人 クリック: 175回
- この商品を含むブログ (7件) を見る
手順
- WPFのプロジェクトで、新規項目の追加⇒コンポーネントクラスを選ぶ(NotifyIconWrapperという名前で作成)
- 作成したコンポーネントクラスのデザイナ画面で、CommonControlsから、NotifyIconを選んでドロップ
- このとき、System.Windows.Forms.dllが参照に追加される
- System.Drawing.dllの参照を手動で追加する。
- ContextMenuStripをドロップする
- NotifyIconを選んで、以下のプロパティを編集する
- Text・・・タスクトレイのアイコン上にカーソルを置いたときに、ツールチップで表示されるテキスト
- Icon・・・タスクトレイに表示されるアイコン
- ContextMenuStrip・・・3.で追加したメニュー
- コンテキストメニューを作成する
- ドロップしたメニュー項目を右クリック⇒項目の編集
- 表示されたエディタでメニューを編集
- コンポーネントクラスのコードビハインドで、メニュー項目を選択した時のイベントハンドラを追加を追加
- 起動時にはウィンドウを表示せず、タスクトレイへの登録を行う
- このままだと、ウィンドウの閉じるボタンを押したときにウィンドウが閉じられてしまうので、以下のどちらかの対処をする
- Closingイベントで、ウィンドウのクローズをキャンセル&ウィンドウを最小化して、タスクバーからも消す
- ウィンドウを閉じるのを許可しておき、再度表示する際に、ウィンドウのインスタンスを再生成する。
(下のコードでは、前者の方法を使ってます)
コード
App.xaml
<Application x:Class="NotifyIcon.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Application.Resources> </Application.Resources> </Application>
App.xaml.cs
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Threading.Tasks; using System.Windows; namespace NotifyIcon { /// <summary> /// App.xaml の相互作用ロジック /// </summary> public partial class App : Application { private NotifyIconWrapper component; protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); this.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; component = new NotifyIconWrapper(); } protected override void OnExit(ExitEventArgs e) { base.OnExit(e); component.Dispose(); } } }
MainWindow.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace NotifyIcon { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { // クローズ処理をキャンセルして、タスクバーの表示も消す e.Cancel = true; this.WindowState = System.Windows.WindowState.Minimized; this.ShowInTaskbar = false; } } }
NotifyIconWrapper.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace NotifyIcon { public partial class NotifyIconWrapper : Component { public NotifyIconWrapper() { InitializeComponent(); // イベントハンドラの設定 toolStripMenuItemShow.Click += toolStripMenuItemShow_Click; toolStripMenuItemExit.Click += toolStripMenuItemExit_Click; // タスクトレイ用のアイコンを設定 System.IO.Stream iconStream = System.Windows.Application.GetResourceStream(new Uri("pack://application:,,,/NotifyIcon;component/Icons/Icon1.ico")).Stream; this.notifyIcon1.Icon = new System.Drawing.Icon(iconStream); } // 常駐させるウィンドウはここで保持する private MainWindow win = new MainWindow(); void toolStripMenuItemShow_Click(object sender, EventArgs e) { ShowWindow(); } void toolStripMenuItemExit_Click(object sender, EventArgs e) { System.Windows.Application.Current.Shutdown(); } private void notifyIcon1_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e) { ShowWindow(); } private void ShowWindow() { // ウィンドウ表示&最前面に持ってくる if (win.WindowState == System.Windows.WindowState.Minimized) win.WindowState = System.Windows.WindowState.Normal; win.Show(); win.Activate(); // タスクバーでの表示をする win.ShowInTaskbar = true; } //public NotifyIconWrapper(IContainer container) //{ // container.Add(this); // InitializeComponent(); //} } }