WPF利用NotifyIcon创建任务栏图标(菜鸟教程)

学习目标:

记录从WPF应用创建开始,一步步到任务栏图标创建的全过程。

流程:

1、环境:Win10 + VS2017

打开VS2017,选择文件 -> 新建 -> 项目 -> Visual C# -> Windows桌面 ->WPF应用(.NET Framework) -> 更改项目名为 TasbarIcon -> 确定
在这里插入图片描述

注意:在VS2022中,要区分:WPF应用程序和WPF应用(.NET Framework),两种类型的项目。

        WPF应用程序:创建的是基于.NET Core类型的项目,可跨平台,可以使用.NET5/6/7/8等。

        WPF应用(.NET Framework):创建的是基于Framework类型的项目,主打Windows上的应用。

 

2、添加图标类

右键项目 -> 添加 ->引用,找到System.Windows.Forms 和 System.Drawing两个程序集,打上勾添加进去。
在这里插入图片描述

双击打开App.xaml.cs文件,在 namespace TaskbarIcon 里面添加图标类代码

//App.xaml.cs
namespace TaskbarIcon
{
    public partial class App : Application
    {
    }

    public class myIcon
    {
        //任务栏图标
        System.Windows.Forms.NotifyIcon notifyIcon = null;

        public void Icon()
        {
            //创建图标
            this.notifyIcon = new System.Windows.Forms.NotifyIcon();

            //程序打开时任务栏会有小弹窗
            this.notifyIcon.BalloonTipText = "PalmServer is running...";

            //鼠标放在图标上时显示的文字
            this.notifyIcon.Text = "PalmServer";

            //图标图片的位置,注意这里要用绝对路径
            this.notifyIcon.Icon = new System.Drawing.Icon("E:/WPF prroject/WpfApp4/WpfApp4/sheep.ico");

            //显示图标
            this.notifyIcon.Visible = true;

            //右键菜单--退出菜单项
            System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("Quit");
            exit.Click += new EventHandler(CloseWindow);

            //关联托盘控件
            System.Windows.Forms.MenuItem[] children = new System.Windows.Forms.MenuItem[] { exit };
            notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(children);

            this.notifyIcon.ShowBalloonTip(1000);
        }

        //退出菜单项对应的处理方式
        public void CloseWindow(object sender, EventArgs e)
        {
            //Dispose()函数能够解决程序退出后图标还在,要鼠标划一下才消失的问题
            this.notifyIcon.Dispose();
            //关闭整个程序
            Application.Current.Shutdown();
        }
    }
}

3、使用图标类

先打开 MainWindow.xaml文件,在里面添加closed事件的声明

//MainWindow.xaml
<Window x:Class="TaskbarIcon.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:TaskbarIcon"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        Closed="Window_Closed">
    <Grid>
        
    </Grid>
</Window>

然后在MainWindo.xaml.cs文件里面使用图标类

//MainWindo.xaml.cs
namespace TaskbarIcon
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ic = new myIcon();
            ic.Icon();

        }
        myIcon ic;

        public void Window_Closed(object sender, EventArgs e)
        {
            ic.CloseWindow(null, null);
            System.Windows.Application.Current.Shutdown();
        }
    }
}

至此,就能创建出自己的程序任务栏图标了!


 

2025-05-29 15:39:36【出处】:https://blog.csdn.net/A_water_/article/details/114950943

=======================================================================================

WPF 通知栏图标和右键菜单

WPF没有自带的通知栏图标组件,需要引用Windows类库,具体代码如下:

        public MainWindow()
        {
            InitializeComponent();
            icon();
            wsl = WindowState.Minimized;
        }

        #region 通知栏
 
            WindowState wsl;
            System.Windows.Forms.NotifyIcon notifyIcon = null;
        
            private void icon()
            {
                this.notifyIcon = new System.Windows.Forms.NotifyIcon();
                this.notifyIcon.BalloonTipText = "ECMS 服务正在运行..."; //设置程序启动时显示的文本
                this.notifyIcon.Text = "ECMS 服务";//最小化到托盘时,鼠标点击时显示的文本
                this.notifyIcon.Icon = new System.Drawing.Icon("./logo_48X48.ico");//程序图标
                this.notifyIcon.Visible = true;
 
                //右键菜单--打开菜单项
                System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("Open");
                open.Click += new EventHandler(ShowWindow);
                //右键菜单--退出菜单项
                System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("Exit");
                exit.Click += new EventHandler(CloseWindow);
                //关联托盘控件
                System.Windows.Forms.MenuItem[] childen = new System.Windows.Forms.MenuItem[] { open, exit };
                notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
 
                notifyIcon.MouseDoubleClick += OnNotifyIconDoubleClick;
                this.notifyIcon.ShowBalloonTip(1000);
            }
 
            private void OnNotifyIconDoubleClick(object sender, EventArgs e)
            {
                /*
                 * 这一段代码需要解释一下:
                 * 窗口正常时双击图标执行这段代码是这样一个过程:
                 * this.Show()-->WindowState由Normail变为Minimized-->Window_StateChanged事件执行(this.Hide())-->WindowState由Minimized变为Normal-->窗口隐藏
                 * 窗口隐藏时双击图标执行这段代码是这样一个过程:
                 * this.Show()-->WindowState由Normail变为Minimized-->WindowState由Minimized变为Normal-->窗口显示
                 */
                this.Show();
                this.WindowState = WindowState.Minimized;
                this.WindowState = WindowState.Normal;
            }
 
            private void Window_StateChanged(object sender, EventArgs e)
            {
                //窗口最小化时隐藏任务栏图标
                 if (WindowState == WindowState.Minimized)
                {
                    this.Hide();
                }
            }
 
            private void ShowWindow(object sender, EventArgs e)
            {
                this.Visibility = System.Windows.Visibility.Visible;
                this.ShowInTaskbar = true;
                this.Activate();
            }
 
            private void HideWindow(object sender, EventArgs e)
            {
                this.ShowInTaskbar = false;
                this.Visibility = System.Windows.Visibility.Hidden;
            }
 
            private void CloseWindow(object sender, EventArgs e)
            {
                System.Windows.Application.Current.Shutdown();
            }
 
        #endregion

 

2025-05-29 15:54:01【出处】:https://blog.csdn.net/zhumingyan/article/details/51136690

=======================================================================================

[WPF]创建系统栏小图标

隐藏窗体任务栏图标#

/// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            this.ShowInTaskbar = false;
        }
    }

 

 

系统图标类 #

  public class SystemTray
    {
        public static SystemTray Instance;
        /// <summary>
        /// 静态构造函数,在类第一次被创建或者静态成员被调用的时候调用
        /// </summary>
        static SystemTray()
        {
            Instance=new SystemTray();
        }

        public NotifyIcon Ni { get; set; }

        private SystemTray()
        {
            Ni = new System.Windows.Forms.NotifyIcon();
            Stream iconStream = Application.GetResourceStream(new Uri("pack://application:,,,/StikyNotes;component/MyLogo.ico")).Stream;
            Ni.Icon = new System.Drawing.Icon(iconStream);
            Ni.Visible = true;
            Ni.MouseClick += Ni_MouseClick;
        }

        private void Ni_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                System.Windows.Controls.ContextMenu NotifyIconMenu = (System.Windows.Controls.ContextMenu)App.Current.FindResource("NotifyIconMenu");
                NotifyIconMenu.IsOpen = true;
                App.Current.MainWindow?.Activate();
            }

            if (e.Button == MouseButtons.Left)
            {
                var wins=WindowsManager.Instance.Windows;
                foreach (var i in wins)
                {
                    i.Activate();
                }
            }
        }

        /// <summary>
        /// 销毁系统托盘图标的资源
        /// </summary>
        public void DisposeNotifyIcon()
        {
            Ni?.Dispose();
        }
    }

 

在App.xaml中:

 public partial class App : Application
    {
        System.Threading.Mutex mutex;
        protected override void OnStartup(StartupEventArgs e)
        {
            bool ret;
            mutex = new System.Threading.Mutex(true, "StikyNotesAPP", out ret);

            if (!ret)
            {
                MessageBox.Show("程序已经运行了");
                Environment.Exit(0);
            }

            base.OnStartup(e);
            var systemtray = SystemTray.Instance;
        }

        protected override void OnDeactivated(EventArgs e)
        {
            base.OnDeactivated(e);
            System.Windows.Controls.ContextMenu menu = this.FindResource("NotifyIconMenu") as ContextMenu;
            if (menu.IsOpen == true)
            {
                menu.IsOpen = false;
            }

        }



        /// <summary>
        /// 新建窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuOpen_Click(object sender, RoutedEventArgs e)
        {
            var MainWindow = new MainWindow();
            MainWindow.DataContext = new MainViewModel(MainWindow, new WindowsData());
            WindowsManager.Instance.Windows.Add(MainWindow);
            MainWindow.Show();
        }

        /// <summary>
        /// 窗体退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuExit_Click(object sender, RoutedEventArgs e)
        {
            SystemTray.Instance.DisposeNotifyIcon();
            App.Current.Shutdown();
        }
        /// <summary>
        /// 窗体退出事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);
            XMLHelper.SaveObjAsXml(ProgramData.Instance, "StikyNotesData.xml");
            SystemTray.Instance.DisposeNotifyIcon();

        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            var programData = XMLHelper.DecodeXML<ProgramData>("StikyNotesData.xml");
            if (programData != null)
            {
                var windowsDatas = programData.Datas;
                ProgramData.Instance.IsWindowTopMost = programData.IsWindowTopMost;
                ProgramData.Instance.IsStartUpWithSystem = programData.IsStartUpWithSystem;
                MainWindow MainWindow;
                //有创建过的窗口
                if (windowsDatas.Count > 0)
                {
                    for (int i = 0; i < windowsDatas.Count; i++)
                    {
                        MainWindow = new MainWindow();
                        MainWindow.DataContext = new MainViewModel(MainWindow, windowsDatas[i]);
                        MainWindow.Show();
                    }
                }
                else//以前的窗口都被删掉了
                {
                    MainWindow = new MainWindow();
                    MainWindow.DataContext = new MainViewModel(MainWindow, new WindowsData());
                    MainWindow.Show();
                }
            }
            //没有创建过的窗口
            else
            {
                var MainWindow = new MainWindow();
                MainWindow.DataContext = new MainViewModel(MainWindow, new WindowsData());
                MainWindow.Show();
            }
        }
    }

App.xaml中
 

 <ContextMenu x:Key="NotifyIconMenu" StaysOpen="False">
                <MenuItem
                    Name="MenuOpen"
                    Click="MenuOpen_Click"
                    Header="新建" />
                <MenuItem
                    Name="MenuExit"
                    Click="MenuExit_Click"
                    Header="退出" />
            </ContextMenu>

问题#

 记得在退出的时候要释放使用的图标资源,否则在程序退出之后,系统栏中还会存在小图标,要使用下面这条语句:

SystemTray.Instance.DisposeNotifyIcon();

 

效果#

 

2025-05-29 15:57:37【出处】:https://www.cnblogs.com/lizhenghao126/p/11053588.html

=======================================================================================

posted on 2025-05-29 15:41  jack_Meng  阅读(47)  评论(0)    收藏  举报

导航