WPF(XAML VB)程序最小化到系统通知托盘报错求助
解决WPF最小化到托盘时notifyIcon为空的问题
核心原因
你遇到的System.NullReferenceException是因为**notifyIcon变量从未被实例化**——WPF框架本身没有内置系统托盘图标控件,直接使用未初始化的变量必然会触发空引用错误。
两种可行解决方案
方案1:依赖Windows Forms组件实现(原生方式)
WPF没有原生托盘控件,可以借助Windows Forms的NotifyIcon来实现:
添加程序集引用
在项目右键菜单中选择「添加引用」,找到System.Windows.Forms和System.Drawing并勾选添加。后台代码实例化并配置NotifyIcon
Imports System.Windows.Forms Imports System.Drawing Partial Public Class MainWindow Inherits Window Private notifyIcon As NotifyIcon Public Sub New() InitializeComponent() ' 构造函数中完成NotifyIcon的实例化与基础配置 notifyIcon = New NotifyIcon() ' 替换为你的图标路径,建议将图标设置为嵌入资源 notifyIcon.Icon = New Icon("Assets/AppIcon.ico") notifyIcon.Text = "你的程序名称" ' 绑定双击托盘图标恢复窗口的事件 AddHandler notifyIcon.DoubleClick, AddressOf OnNotifyIconDoubleClick End Sub ' 窗口状态变化事件处理 Private Sub Window_StateChanged(sender As Object, e As EventArgs) If Me.WindowState = WindowState.Minimized Then Me.Visibility = Visibility.Hidden notifyIcon.Visible = True End If End Sub ' 双击托盘图标恢复窗口 Private Sub OnNotifyIconDoubleClick(sender As Object, e As EventArgs) Me.Visibility = Visibility.Visible Me.WindowState = WindowState.Normal notifyIcon.Visible = False End Sub ' 窗口关闭时清理托盘图标,避免程序退出后图标残留 Protected Overrides Sub OnClosed(e As EventArgs) MyBase.OnClosed(e) notifyIcon.Dispose() End Sub End ClassXAML绑定状态变化事件
在Window标签中添加StateChanged事件绑定:<Window x:Class="YourProjectNamespace.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="450" Width="800" StateChanged="Window_StateChanged"> <!-- 窗口内容 --> </Window>
方案2:使用WPF专用托盘控件库(更推荐)
如果不想依赖Windows Forms,可以使用专为WPF设计的Hardcodet.NotifyIcon.Wpf库:
NuGet安装库
在NuGet包管理器中搜索Hardcodet.NotifyIcon.Wpf并安装。XAML中声明托盘控件
<Window x:Class="YourProjectNamespace.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:tb="http://www.hardcodet.net/taskbar" Title="MainWindow" Height="450" Width="800" StateChanged="Window_StateChanged"> <!-- 托盘控件,默认隐藏 --> <tb:TaskbarIcon x:Name="notifyIcon" IconSource="Assets/AppIcon.ico" ToolTipText="你的程序名称" Visibility="Collapsed"> <!-- 可选:添加右键菜单 --> <tb:TaskbarIcon.ContextMenu> <ContextMenu> <MenuItem Header="恢复窗口" Click="RestoreWindow_Click"/> <MenuItem Header="退出程序" Click="ExitApp_Click"/> </ContextMenu> </tb:TaskbarIcon.ContextMenu> </tb:TaskbarIcon> <!-- 窗口内容 --> </Window>后台代码处理最小化与恢复逻辑
Partial Public Class MainWindow Inherits Window Private Sub Window_StateChanged(sender As Object, e As EventArgs) If Me.WindowState = WindowState.Minimized Then Me.Visibility = Visibility.Hidden notifyIcon.Visibility = Visibility.Visible End If End Sub Private Sub RestoreWindow_Click(sender As Object, e As RoutedEventArgs) Me.Visibility = Visibility.Visible Me.WindowState = WindowState.Normal notifyIcon.Visibility = Visibility.Collapsed End Sub Private Sub ExitApp_Click(sender As Object, e As RoutedEventArgs) Me.Close() End Sub End Class
关键注意事项
- 无论哪种方案,必须保证
notifyIcon在使用前完成初始化——要么在构造函数中实例化,要么通过XAML声明。 - 使用Windows Forms的
NotifyIcon时,程序退出前一定要调用Dispose(),防止托盘图标残留。 - 图标文件路径要确保正确,建议将图标设置为项目的嵌入资源,避免路径问题。
内容的提问来源于stack exchange,提问作者rurjaf
相关产品推荐
相关产品推荐

