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日

相关文章

  • grafana下载与安装(v5.4.1)

    Grafana下载与安装(v5.4.1) Grafana是一款流行的开源数据可视化工具,它可以将各种数据源转换为漂亮的图表。本文将演示如何在Linux系统中下载安装Grafana(版本为v5.4.1)。 步骤一:下载Grafana安装包 在Grafana的官方网站 https://grafana.com/grafana/download 中,我们可以找到Gr…

    其他 2023年3月28日
    00
  • java对象判空方法

    简介 在Java编程中,我们经常需要判断一个对象是否为空。在本攻略中,我们将介绍Java中常用的对象判空方法,以及如何使用它们。 方法 以下是Java中用的对象判空方法。 方法1:使用“==”运算符 在Java中,我们可以使用“==”运算符来判断一个对象是否为空。如果对象为null,则返回true;否则返回false。以下是使用“==”运算符判断对象是否为空…

    other 2023年5月6日
    00
  • Windows11记事本打不开怎么办?Win11记事本提示无法启动此应用程序的解决方法

    Windows11记事本打不开怎么办? 在Windows 11系统中,记事本是一个非常常用的系统工具,但有时会出现无法启动的情况,这时候可能会提示“无法启动此应用程序”,该如何解决呢? 解决方法 方法1:使用命令提示符修复记事本 使用管理员权限打开命令提示符。在开始菜单中搜索“命令提示符”,然后右键点击,选择“以管理员身份运行”。 执行如下命令: Get-A…

    other 2023年6月25日
    00
  • 关于gitversion主线:gitversion主线-每次推送的版本增量

    以下是关于GitVersion主线每次推送的版本增量的完整攻略,包括基本知识和两个示例说明。 基本知识 GitVersion是一个自动版本控制工具,它可以根据Git提交历史记录自动计算版本号。GitVersion主线是GitVersion的主要分支,它包含了GitVersion的最新功能和修复的错误。 在GitVersion主线中,每次推送都会增加版本号。G…

    other 2023年5月7日
    00
  • WxJava微信公众号开发入门实战

    WxJava是一个Java语言开发的微信公众号SDK,我们可以使用它快速开发微信公众号应用。下面是WxJava微信公众号开发的完整攻略。 1. 准备工作 在开始微信公众号开发前,我们需要完成以下准备工作: 注册微信公众平台账号; 成为微信公众平台开发者; 创建测试公众号; 获取微信公众号的AppID和AppSecret; 下载并导入WxJava SDK。 2…

    other 2023年6月27日
    00
  • 如何解决应用程序或dll 为无效的windows映像的问题

    问题描述: 当你尝试启动程序或应用程序时,你可能会收到一个错误提示,如“应用程序或dll文件不是Windows映像”,这意味着你尝试运行的程序或应用所依赖的dll文件被损坏或缺失,导致Windows无法正确加载该文件。这是一个常见的问题,下面我将为您提供解决此问题的完整攻略。 解决步骤如下: 步骤1:卸载并重新安装有问题的程序 首先,你应该尝试卸载有问题的程…

    other 2023年6月25日
    00
  • Windows下用命令行修改IP地址的方法详解(附批处理文件)

    下面是详细的“Windows下用命令行修改IP地址的方法详解(附批处理文件)”攻略。 什么是IP地址以及IP地址的基础知识 在开始之前,我们需要先了解一下IP地址以及相关的基础概念。 IP地址 IP地址是Internet协议(Internet Protocol)地址的简称,它是网络上设备的唯一标识符。网络上的所有设备,包括计算机、服务器、路由器等都需要有唯一…

    other 2023年6月26日
    00
  • 总结一下时下流行的浏览器User-Agent大全

    总结一下时下流行的浏览器User-Agent大全攻略 什么是User-Agent? User-Agent是一个HTTP请求头部字段,用于标识发送请求的客户端应用程序、操作系统、设备类型等信息。浏览器User-Agent是指浏览器发送的User-Agent字符串,其中包含了浏览器的相关信息。 流行的浏览器User-Agent大全 以下是一些时下流行的浏览器Us…

    other 2023年8月3日
    00
合作推广
合作推广
分享本页
返回顶部