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

最近都没怎么接触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();

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

 

 DEMO:/Files/leeolevis/NotifiWpfAppl.rar

posted @ 2011-06-14 13:16  leeolevis  阅读(2526)  评论(3编辑  收藏  举报