C# 实现WPF App最小化托盘测试

WPF 需要添加Windows.Forms 组件。

xmlns:winForm ="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

前台XAML代码如下:

<Window x:Class="WpfApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp" xmlns:winForm ="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" xmlns:drawing="clr-namespace:System.Drawing;assembly=System.Drawing" StateChanged="Window_StateChanged" SizeChanged="Window_SizeChanged" mc:Ignorable="d" Title="最小化到托盘测试" Height="250" Width="400"> <Grid> <local:NotificationAreaIcon x:Name="notfyicon" Text="我是测试代码" Icon="red.ico" MouseDoubleClick="NotificationAreaIcon_MouseDoubleClick"> <local:NotificationAreaIcon.MenuItems> <winForm:MenuItem x:Name="MenuIteOnline" Click="MenuIteOnline_Click"> <winForm:MenuItem.Text>在线</winForm:MenuItem.Text> </winForm:MenuItem> <winForm:MenuItem Text="离开" x:Name="MenuItemLeave" Click="MenuItemLeave_Click"/> <winForm:MenuItem Text="请勿打扰" x:Name="MenuItemNoBother" Click="MenuItemNoBother_Click"/> <winForm:MenuItem Text="忙碌" x:Name="MenuItemBusy" Click="MenuItemBusy_Click"/> <winForm:MenuItem Text="隐身" x:Name="MenuItemHidden" Click="MenuItemHidden_Click"/> <winForm:MenuItem Text="离线" x:Name="MenuItemOffline" Click="MenuItemOffline_Click"/> <winForm:MenuItem Text="关于" x:Name="MenuItemAboutUs" Click="MenuItemAboutUs_Click"/> <winForm:MenuItem Text="退出" x:Name="MenuItemExit" Click="MenuItemExit_Click"/> </local:NotificationAreaIcon.MenuItems> </local:NotificationAreaIcon> </Grid> </Window>


添加实现的类 NotificationAreaIcon.cs:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.ComponentModel;

using Drawing = System.Drawing;

using Forms = System.Windows.Forms; //Forms.NotifyIcon

using System.Windows;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Markup;

namespace WpfApp

{

    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

    }

}


Windows UI 后台代码:

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 WpfApp

{

    /// <summary>

    /// MainWindow.xaml 的交互逻辑

    /// </summary>

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

            this.ShowInTaskbar = false;

        }

        private void Window_StateChanged(object sender, EventArgs e)

        {

            if (this.WindowState == WindowState.Minimized)

            {

                this.Hide();

            }

            if (this.WindowState == WindowState.Normal || this.WindowState == WindowState.Maximized)

            {

                this.Show();

                this.Activate();

            }

        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)

        {

            if (this.WindowState == WindowState.Minimized)

            {

                this.ShowInTaskbar = false;

                this.Hide();

                this.notfyicon.Visibility = Visibility.Visible;

            }

        }

        //双击托盘图标恢复需要响应notifyIcon的DoubleClick消息

        private void NotificationAreaIcon_MouseDoubleClick(object sender, MouseButtonEventArgs e)

        {

            if (this.WindowState == WindowState.Minimized)

            {

                this.Show();

                WindowState = WindowState.Normal;

                this.notfyicon.Visibility = Visibility.Hidden;

                this.ShowInTaskbar = true;

            }

        }

        private void MenuItemLeave_Click(object sender, EventArgs e)

        {

            MessageBox.Show("提示离线!");

        }

        private void MenuItemNoBother_Click(object sender, EventArgs e)

        {

            MessageBox.Show("提示请勿打扰!");

        }

        private void MenuItemBusy_Click(object sender, EventArgs e)

        {

            MessageBox.Show("提示在忙!");

        }

        private void MenuItemHidden_Click(object sender, EventArgs e)

        {

            MessageBox.Show("提示隐身!");

        }

        private void MenuItemOffline_Click(object sender, EventArgs e)

        {

            MessageBox.Show("提示暂时离开!");

        }

        private void MenuItemAboutUs_Click(object sender, EventArgs e)

        {

            MessageBox.Show("提示关于我们!");

        }

        private void MenuItemExit_Click(object sender, EventArgs e)

        {

            this.Close();

        }

        private void MenuIteOnline_Click(object sender, EventArgs e)

        {

            MessageBox.Show("提示上线!");

        }

    }

}


运行测试如下:


最小化,在状态栏显示指定logo.


右键弹出菜单:



代码可响应任何一个菜单的事件。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容