Press "Enter" to skip to content

Come creare un applicazione WPF che rimane in esecuzione mostrando icona e menu in Tray Area

A seguito di una richiesta effettuata sul forum italiano Microsoft, esattamente Questo Thread ho deciso che oltre all’articolo che mostra come usare la Notify Icon di Windows forms per mostrare la sua icona nella Tray Area di scrivere anche lo stesso progetto per WPF, pertanto sono andata a cercare il componente corrispondente nel framework WPF. Sfortunatamente, come per altri controlli, non esiste un controllo standard del framework che permetta di fare tutto ciò. La soluzione più semplicemente suggerita è quella di utilizzare il controllo Windows Forms oppure un controllo di terze parti.

Se volete utilizzare un controllo avanazato scritto da un “code addict” e disponibile gratuitamente, ecco il link al blog di Philipp Sumi dove potete trovare il controllo WPF Notify Icon, e se mi scappa magari farò un post utilizzandolo.

Io invece, faccio l’esempio da pigrizia totale e utilizzerò il controllo Windows Forms, anche perché serve a dimostrare l’interoperabilità fra Windows Forms e WPF.

solution_01

La nostra soluzione è molto semplice, abbiamo la nostra main window standard di WPF in cui abbiamo messo 3 controlli solo per non lasciarla vuota.

mainwindow_01

Il succo dell’applicazione ovviamente sta nel code behind.

private bool mRequestClose;


private bool RequestClose
{
get
{
return mRequestClose;
}
set
{
mRequestClose = value;
}
}

Innanzi tutto inseriamo la property boolean che useremo per attivare la chiusura dell’applicazione.

public MainWindow()
{
InitializeComponent();
this.Icon = BitmapFrame.Create(new Uri("pack://application:,,,/MBMLogoS.ico", UriKind.RelativeOrAbsolute));
System.Windows.Forms.ContextMenuStrip cms = new System.Windows.Forms.ContextMenuStrip();
cms.ItemClicked += Cms_ItemClicked;
System.Windows.Forms.ToolStripMenuItem tsmi = new System.Windows.Forms.ToolStripMenuItem();
tsmi.Name = "mnuOpen";
tsmi.Text = "Open";
cms.Items.Add(tsmi);

tsmi = new System.Windows.Forms.ToolStripMenuItem();
tsmi.Name = "mnuSettings";
tsmi.Text = "Settings";
cms.Items.Add(tsmi);

tsmi = new System.Windows.Forms.ToolStripMenuItem();
tsmi.Name = "mnuClose";
tsmi.Text = "Close";
cms.Items.Add(tsmi);


System.Windows.Forms.NotifyIcon ni = new System.Windows.Forms.NotifyIcon();
ni.Icon = Properties.Resources.MBMLogoS;
ni.Visible = true;
ni.ContextMenuStrip = cms;
RequestClose = false;
this.ShowInTaskbar = false;
this.Closing += MainWindow_Closing;
}

non potendo usare i componenti windows forms nello XAML li istanziamo da codice nel costruttore della window, e esattamente lo stesso tipo di codice creato nel precedente post dal designer delle windows form.

Da notare, la property ShowInTaskBar  posta a false e l’event handler per l’evento Closing della window.

private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!RequestClose)
{
WindowState = WindowState.Minimized;
e.Cancel = true;
}
}

Sfortunatamente, la closing di WPF non informa sul tipo di chiusura richiesto, quindi non sappiamo se richiesto da utente o dal sistema. Ci sono altri modi per pilotare uno shutdown in WPF. Nel nostro caso, se non è stata richiesta chiusura, minimizziamo la finestra.

private void Cms_ItemClicked(object sender, System.Windows.Forms.ToolStripItemClickedEventArgs e)
{
System.Windows.Forms.ToolStripItem item = e.ClickedItem;
switch (item.Name)
{
case "mnuOpen":
this.WindowState = WindowState.Normal;
this.BringIntoView();
break;
case "mnuSettings":
MessageBox.Show("Settings Menu");
break;
case "mnuClose":
RequestClose = true;
Close();
break;
}
}

L’event handler del menu contestuale è identico a quello visto sul post per Windows forms, open riapre e visualizza la finestra, Settings esegue un azione, Close chiude l’applicazione.

mainwindow_02

Riepilogo

In questo esempio abbiamo visto le seguenti cose:

  • Come usare il componente NotifyIcon per fare apparire l’icona dell’applicazione nella Tray Area di Windows in una applicazione WPF.
  • Come agganciare un ContextMenuStrip alla NotifyIcon per permettergli di eseguire una serie di azioni.
  • Come non mostrare una Window sulla TaskBar.

Potete scaricare il progetto esempio dal link qui indicato:

Per qualsiasi domanda, osservazione, commento, approfondimento, o per segnalare un errore, potete usare il link alla form di contatto in cima alla pagina.