创建基于系统托盘的WPF程序

时间:2022-06-27 03:40:41

最近都没怎么接触WPF了,闲来无事为以前做的WPF DEMO添加托盘管理。 

http://www.cnblogs.com/leeolevis/archive/2010/07/14/1777658.html 

其中,主要添加了NotificationAreaIcon类,代码如下:

using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Windows;
using  System.Windows.Input;
using  System.Windows.Markup;
using  System.Windows.Media;
using  System.Windows.Threading;
using  Drawing  =  System.Drawing;
using  Forms  =  System.Windows.Forms;

namespace  WpfApplication1
{
    
///   <summary>
    
///  Represents a thin wrapper for  <see cref="Forms.NotifyIcon"/>
    
///   </summary>
    [ContentProperty( " Text " )]
    [DefaultEvent(
" MouseDoubleClick " )]
    
public   class  NotificationAreaIcon : FrameworkElement
    {
        Forms.NotifyIcon notifyIcon;

        
public   static   readonly  RoutedEvent MouseClickEvent  =  EventManager.RegisterRoutedEvent(
            
" MouseClick " , RoutingStrategy.Bubble,  typeof (MouseButtonEventHandler),  typeof (NotificationAreaIcon));

        
public   static   readonly  RoutedEvent MouseDoubleClickEvent  =  EventManager.RegisterRoutedEvent(
            
" MouseDoubleClick " , RoutingStrategy.Bubble,  typeof (MouseButtonEventHandler),  typeof (NotificationAreaIcon));

        
public   static   readonly  DependencyProperty IconProperty  =
            DependencyProperty.Register(
" Icon " typeof (ImageSource),  typeof (NotificationAreaIcon));

        
public   static   readonly  DependencyProperty TextProperty  =
            DependencyProperty.Register(
" Text " typeof ( string ),  typeof (NotificationAreaIcon));

        
public   static   readonly  DependencyProperty FormsContextMenuProperty  =
            DependencyProperty.Register(
" MenuItems " typeof (List < Forms.MenuItem > ),  typeof (NotificationAreaIcon),  new  PropertyMetadata( new  List < Forms.MenuItem > ()));

        
protected   override   void  OnInitialized(EventArgs e)
        {
            
base .OnInitialized(e);

            
//  Create and initialize the window forms notify icon based
            notifyIcon  =   new  Forms.NotifyIcon();
            notifyIcon.Text 
=  Text;
            
if  ( ! DesignerProperties.GetIsInDesignMode( this ))
            {
                notifyIcon.Icon 
=  FromImageSource(Icon);
            }
            notifyIcon.Visible 
=  FromVisibility(Visibility);

            
if  ( this .MenuItems  !=   null   &&   this .MenuItems.Count  >   0 )
            {
                notifyIcon.ContextMenu 
=   new  System.Windows.Forms.ContextMenu( this .MenuItems.ToArray());
            }

            notifyIcon.MouseDown 
+=  OnMouseDown;
            notifyIcon.MouseUp 
+=  OnMouseUp;
            notifyIcon.MouseClick 
+=  OnMouseClick;
            notifyIcon.MouseDoubleClick 
+=  OnMouseDoubleClick;

            Dispatcher.ShutdownStarted 
+=  OnDispatcherShutdownStarted;
        }

        
private   void  OnDispatcherShutdownStarted( object  sender, EventArgs e)
        {
            notifyIcon.Dispose();
        }

        
private   void  OnMouseDown( object  sender, Forms.MouseEventArgs e)
        {
            OnRaiseEvent(MouseDownEvent, 
new  MouseButtonEventArgs(
                InputManager.Current.PrimaryMouseDevice, 
0 , ToMouseButton(e.Button)));
        }

        
private   void  OnMouseUp( object  sender, Forms.MouseEventArgs e)
        {
            OnRaiseEvent(MouseUpEvent, 
new  MouseButtonEventArgs(
                InputManager.Current.PrimaryMouseDevice, 
0 , ToMouseButton(e.Button)));
        }

        
private   void  OnMouseDoubleClick( object  sender, Forms.MouseEventArgs e)
        {
            OnRaiseEvent(MouseDoubleClickEvent, 
new  MouseButtonEventArgs(
                InputManager.Current.PrimaryMouseDevice, 
0 , ToMouseButton(e.Button)));
        }

        
private   void  OnMouseClick( object  sender, Forms.MouseEventArgs e)
        {
            OnRaiseEvent(MouseClickEvent, 
new  MouseButtonEventArgs(
                InputManager.Current.PrimaryMouseDevice, 
0 , ToMouseButton(e.Button)));
        }

        
private   void  OnRaiseEvent(RoutedEvent handler, MouseButtonEventArgs e)
        {
            e.RoutedEvent 
=  handler;
            RaiseEvent(e);
        }

        
public  List < Forms.MenuItem >  MenuItems
        {
            
get  {  return  (List < Forms.MenuItem > )GetValue(FormsContextMenuProperty); }
            
set  { SetValue(FormsContextMenuProperty, value); }
        }

        
public  ImageSource Icon
        {
            
get  {  return  (ImageSource)GetValue(IconProperty); }
            
set  { SetValue(IconProperty, value); }
        }

        
public   string  Text
        {
            
get  {  return  ( string )GetValue(TextProperty); }
            
set  { SetValue(TextProperty, value); }
        }

        
public   event  MouseButtonEventHandler MouseClick
        {
            add { AddHandler(MouseClickEvent, value); }
            remove { RemoveHandler(MouseClickEvent, value); }
        }

        
public   event  MouseButtonEventHandler MouseDoubleClick
        {
            add { AddHandler(MouseDoubleClickEvent, value); }
            remove { RemoveHandler(MouseDoubleClickEvent, value); }
        }

        
#region  Conversion members

        
private   static  Drawing.Icon FromImageSource(ImageSource icon)
        {
            
if  (icon  ==   null )
            {
                
return   null ;
            }
            Uri iconUri 
=   new  Uri(icon.ToString());
            
return   new  Drawing.Icon(Application.GetResourceStream(iconUri).Stream);
        }

        
private   static   bool  FromVisibility(Visibility visibility)
        {
            
return  visibility  ==  Visibility.Visible;
        }

        
private  MouseButton ToMouseButton(Forms.MouseButtons button)
        {
            
switch  (button)
            {
                
case  Forms.MouseButtons.Left:
                    
return  MouseButton.Left;
                
case  Forms.MouseButtons.Right:
                    
return  MouseButton.Right;
                
case  Forms.MouseButtons.Middle:
                    
return  MouseButton.Middle;
                
case  Forms.MouseButtons.XButton1:
                    
return  MouseButton.XButton1;
                
case  Forms.MouseButtons.XButton2:
                    
return  MouseButton.XButton2;
            }
            
throw   new  InvalidOperationException();
        }

        
#endregion  Conversion members
    }

  } 

  

在主窗口上引用该命名控件 xmlns:l="clr-namespace:WpfApplication1"

在主窗口里添加如下代码

         < l:NotificationAreaIcon
                      Text
= " NotificationAreaApplication1 "
                      Icon
= " Resources\NotificationAreaIcon.ico "
                      MouseDoubleClick
= " OnNotificationAreaIconDoubleClick "  Grid.ColumnSpan = " 2 " >
            
< l:NotificationAreaIcon.MenuItems >
                
< forms:MenuItem Text = " 关于作者 "  Click = " OnMenuItemAboutClick " />
                
< forms:MenuItem Text = " - "   />
                
< forms:MenuItem Text = " Open "  Click = " OnMenuItemOpenClick "  DefaultItem = " True "   />
                
< forms:MenuItem Text = " - "   />
                
< forms:MenuItem Text = " Exit "  Click = " OnMenuItemExitClick "   />
            
</ l:NotificationAreaIcon.MenuItems >

   </l:NotificationAreaIcon>  

后台定义如下状态,并重载其Window类的OnStateChanged和OnClosing方法,代码如下:

        WindowState lastWindowState;
        
bool  shouldClose;

        
public  MainWindow()
        {
            InitializeComponent();
            
this .Loaded  +=   new  RoutedEventHandler(MainWindow_Loaded);
        }

        
private   void  MainWindow_Loaded( object  sender, RoutedEventArgs e)
        {
            DataBind();
        }

        
protected   override   void  OnStateChanged(EventArgs e)
        {
            lastWindowState 
=  WindowState;
        }

        
protected   override   void  OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            
if  ( ! shouldClose)
            {
                e.Cancel 
=   true ;
                Hide();
            }

并为托盘菜单添加事件:

         protected   void  OnMenuItemAboutClick( object  sender, EventArgs e)
        {
            
new  Window1().Show();
        }

        
private   void  OnNotificationAreaIconDoubleClick( object  sender, MouseButtonEventArgs e)
        {
            
if  (e.ChangedButton  ==  MouseButton.Left)
            {
                Open();
            }
        }

        
private   void  OnMenuItemOpenClick( object  sender, EventArgs e)
        {
            Open();
        }

        
private   void  Open()
        {
            Show();
            WindowState 
=  lastWindowState;
        }

        
private   void  OnMenuItemExitClick( object  sender, EventArgs e)
        {
            shouldClose 
=   true ;
            Close();

完成,运行我们的程序,看到托盘已经有我们添加的菜单了:

创建基于系统托盘的WPF程序 

 DEMO:/Files/leeolevis/NotifiWpfAppl.rar