WPF实现基础控件之托盘的示例代码

下面是WPF实现托盘的完整攻略:

一、前期准备

在开始编写代码之前,首先需要在项目中添加两个NuGet包:

这两个包的添加方式可以通过NuGet包管理器或在项目文件中手动添加。

二、定义托盘图标和菜单

在主窗口中添加托盘图标,并在托盘图标的上下文菜单中添加菜单项,可以通过以下代码实现:

<Window ...>
    ...
    <Window.Resources>
        <tray:TaskbarIcon x:Key="NotifyIcon" IconSource="icon.ico">
            <tray:TaskbarIcon.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="打开窗口" Command="{Binding OpenWindowCommand}" />
                    <Separator />
                    <MenuItem Header="退出" Command="{Binding ExitCommand}" />
                </ContextMenu>
            </tray:TaskbarIcon.ContextMenu>
        </tray:TaskbarIcon>
    </Window.Resources>
    ...
</Window>

上述代码中,tray是指向Hardcodet.NotifyIcon.Wpf命名空间的XAML命名空间,icon.ico是托盘图标的路径。同时,在托盘图标的上下文菜单中定义了两个菜单项,分别绑定到主窗口ViewModel中的OpenWindowCommandExitCommand命令。

三、实现托盘功能

在主窗口ViewModel中,实现托盘功能需要完成以下几个步骤:

  1. 定义一个NotifyIcon对象,并在视图中绑定到托盘图标。
public class MainViewModel : INotifyPropertyChanged
{
    ...
    private readonly NotifyIcon _notifyIcon;

    public MainViewModel()
    {
        _notifyIcon = (NotifyIcon)Application.Current.FindResource("NotifyIcon");
        ...
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    ...
}

在ViewModel的构造函数中获取在视图中定义的NotifyIcon对象,并保存到一个私有字段,以便后续使用。

  1. 定义OpenWindowCommand和ExitCommand命令,并实现相应的功能。
public class MainViewModel : INotifyPropertyChanged
{
    ...
    public ICommand OpenWindowCommand => new DelegateCommand(() =>
    {
        // 显示或激活主窗口
        var mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
        if (mainWindow != null)
        {
            mainWindow.Show();
            if (mainWindow.WindowState == WindowState.Minimized)
            {
                mainWindow.WindowState = WindowState.Normal;
            }
            mainWindow.Activate();
        }
    });

    public ICommand ExitCommand => new DelegateCommand(() =>
    {
        // 关闭应用程序
        Application.Current.Shutdown();
    });
    ...
}

上述代码中,OpenWindowCommand命令用于打开或激活主窗口,ExitCommand命令用于退出应用程序。

  1. 添加对WindowState的监听,实现窗口最小化时隐藏窗口并显示托盘图标。
public class MainViewModel : INotifyPropertyChanged
{
    ...
    public MainViewModel()
    {
        _notifyIcon = (NotifyIcon)Application.Current.FindResource("NotifyIcon");
        ...
        // 添加对WindowState的监听
        var mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
        if (mainWindow != null)
        {
            mainWindow.StateChanged += (sender, e) =>
            {
                switch (mainWindow.WindowState)
                {
                    case WindowState.Minimized:
                        mainWindow.Hide();
                        _notifyIcon.ShowBalloonTip("提示", "应用程序已最小化到托盘", BalloonIcon.Info);
                        break;
                    case WindowState.Normal:
                        _notifyIcon.HideBalloonTip();
                        break;
                }
            };
        }
    }
    ...
}

在构造函数中获取主窗口对象,并添加对WindowState的监听。当窗口状态变为最小化时,隐藏窗口并显示一个气泡提示,提醒用户应用程序已经最小化到托盘。

  1. 实现托盘图标的交互行为,如右键菜单打开主窗口。
public class MainViewModel : INotifyPropertyChanged
{
    ...
    public MainViewModel()
    {
        ...
        // 实现交互行为
        Interaction.GetBehaviors(_notifyIcon).Add(new TaskbarIconBehavior(OpenWindowCommand));
    }
    ...
}

public class TaskbarIconBehavior : Behavior<NotifyIcon>
{
    private readonly ICommand _command;

    public TaskbarIconBehavior(ICommand command)
    {
        _command = command;
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.TrayMouseDoubleClick += AssociatedObjectOnTrayMouseDoubleClick;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.TrayMouseDoubleClick -= AssociatedObjectOnTrayMouseDoubleClick;
    }

    private void AssociatedObjectOnTrayMouseDoubleClick(object sender, RoutedEventArgs e)
    {
        _command.Execute(null);
    }
}

在主窗口ViewModel中,通过Behavior将托盘图标的交互行为定义为一个类,该类实现OnAttachedOnDetaching等相关方法,将双击图标打开主窗口的逻辑绑定到OpenWindowCommand命令上。

至此,WPF实现托盘的工作完毕。

四、示例说明

  1. 如何使用NotifyIcon显示气泡提示?

可以通过ShowBalloonTip方法显示气泡提示,方法参数包括提示标题、提示消息和提示图标。例如:

_notifyIcon.ShowBalloonTip("提示", "这是一条气泡提示", BalloonIcon.Info);
  1. 如何在托盘图标上添加自定义图标?

可以通过在托盘图标的XAML中指定IconSource属性实现自定义图标。例如:

<tray:TaskbarIcon IconSource="my_icon.ico">

其中my_icon.ico是自定义图标的文件名。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:WPF实现基础控件之托盘的示例代码 - Python技术站

(1)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • C语言实现单链表的基本功能详解

    C语言实现单链表的基本功能详解 简介 单链表是一种常见的数据结构,由一系列的节点(Node)组成,每个节点包含数据和指向下一个节点的指针,最后一个节点的指针为NULL。C语言实现单链表需要掌握指针和动态内存分配的知识,具有一定难度。本文将详细讲解C语言实现单链表的基本功能。 基本结构 定义单链表结点的结构体,包括数据和指向下一个结点的指针,如下所示: typ…

    other 2023年6月27日
    00
  • 详解批处理文件语法

    详解批处理文件语法 批处理文件是Windows操作系统中的一种脚本文件, 可以通过命令行方式执行一系列命令, 用于进行批量处理。 一般来说, 批处理文件的扩展名为.bat或.cmd, 文件开头一般需要添加@echo off命令, 以隐藏执行过程中的命令行窗口和输出内容。 以下是批处理文件的基本语法: @echo off REM 这里是注释,在脚本中不会被执行…

    other 2023年6月26日
    00
  • vscode远程免密登入Linux服务器的配置方法

    下面是“vscode远程免密登入Linux服务器的配置方法”的完整攻略,步骤如下: 1. 安装必要的软件 在进行配置之前,需要先确保本地电脑中已经安装了必要的软件,包括: VS Code编辑器 OpenSSH 客户端 Remote-SSH插件 其中,OpenSSH 客户端是远程访问 Linux 服务器的工具,Remote-SSH插件则是 VS Code 所提…

    other 2023年6月27日
    00
  • 微软Win11乱改?这才是Win11右键菜单最完美解决方法!

    我来为您详细讲解关于微软Win11右键菜单最完美解决方法的攻略。 背景 最近有不少Win11用户反映,在系统升级后,右键菜单出现了很多不需要的功能,导致菜单变得很乱。这个问题困扰着很多用户,但是微软并没有提供快速解决的方法。接下来,我将为大家介绍最完美的Win11右键菜单解决方法。 方案 我们可以通过一些第三方软件和系统设置来解决Win11右键菜单的问题。具…

    other 2023年6月27日
    00
  • C++关于类结构体大小和构造顺序,析构顺序的测试详解

    C++关于类结构体大小和构造顺序,析构顺序的测试详解 概述 在C++中,类和结构体具有相同的定义方式,而它们的大小、内存分配方式,构造和析构顺序等等却有所不同。本文将从各个方面渐进式地介绍类和结构体之间的差异,希望能够帮助大家更好地理解和使用C++语言。 类和结构体的内存分配 在C++中,类和结构体可以直接定义成员变量和成员函数,并在其中定义多个类型的数据。…

    other 2023年6月26日
    00
  • 怎么使用linux搭建vpn?

    下面就为你详细讲解如何使用 Linux 搭建 VPN 的完整攻略。 1. 确认 Linux 系统版本和内核版本 首先,需要确认使用的 Linux 系统版本和内核版本是否支持 VPN。使用以下命令查看系统版本和内核版本: $ cat /etc/*release* $ uname -r 2. 安装 VPN 服务端 VPN 服务可以使用多种选择,例如 OpenVP…

    其他 2023年4月16日
    00
  • Android Studio将程序打包成APK的步骤详解

    下面是Android Studio将程序打包成APK的步骤详解: 1. 确保Android Studio配置正确 在开始打包APK之前,请确保Android Studio已正确配置,并且Gradle已经正确安装。如果你不确定是否已经完成这些步骤,建议你参考Android Studio的官方文档进行配置。 2. 配置build.gradle文件 在进行打包AP…

    other 2023年6月25日
    00
  • matplotlib 入门之Image tutorial

    Matplotlib 入门之 Image Tutorial 在 Matplotlib 中,可以利用图像、矩阵和 DataFrame 数据来进行高质量的图形绘制。 加载图像 要加载图像,我们需要导入 matplotlib.image 包。 import matplotlib.image as mpimg import matplotlib.pyplot as …

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部