From 424311f088184552d64cbdda833f3e38e1a75f3b Mon Sep 17 00:00:00 2001 From: XuShanQiXun <3401460572@qq.com> Date: Sat, 7 Jun 2025 16:10:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E6=89=98=E7=9B=98=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=92=8C=E7=95=8C=E9=9D=A2=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 `App.xaml` 中更新资源字典,添加 `MaterialTrayMenuItem.xaml` 以支持托盘菜单样式。 在 `MainWindow.xaml` 中添加 `Closed` 和 `Loaded` 事件处理程序。 在 `MainWindow.xaml.cs` 中引入 `TrayIconManager`,管理系统托盘图标及其行为。 更新 `chatclient.csproj` 中 `chat.ico` 的属性以确保复制到输出目录。 在 `MaterialTrayMenuItem.xaml` 中定义 Material Design 风格的托盘菜单项和上下文菜单样式。 创建 `TrayIconManager.cs` 类以优化托盘图标的创建和事件处理,提升用户体验。 --- chatclient/App.xaml | 17 +-- chatclient/Data/MaterialTrayMenuItem.xaml | 45 ++++++++ chatclient/Data/TrayIconManager.cs | 122 ++++++++++++++++++++++ chatclient/MainWindow.xaml | 2 +- chatclient/MainWindow.xaml.cs | 16 +++ chatclient/chatclient.csproj | 4 +- 6 files changed, 196 insertions(+), 10 deletions(-) create mode 100644 chatclient/Data/MaterialTrayMenuItem.xaml create mode 100644 chatclient/Data/TrayIconManager.cs diff --git a/chatclient/App.xaml b/chatclient/App.xaml index 234aed7..43f4d3c 100644 --- a/chatclient/App.xaml +++ b/chatclient/App.xaml @@ -5,14 +5,15 @@ xmlns:local="clr-namespace:chatclient" StartupUri="MainWindow.xaml"> - - - - - - + + + + + + + - - + + diff --git a/chatclient/Data/MaterialTrayMenuItem.xaml b/chatclient/Data/MaterialTrayMenuItem.xaml new file mode 100644 index 0000000..5387ae3 --- /dev/null +++ b/chatclient/Data/MaterialTrayMenuItem.xaml @@ -0,0 +1,45 @@ + + + + + \ No newline at end of file diff --git a/chatclient/Data/TrayIconManager.cs b/chatclient/Data/TrayIconManager.cs new file mode 100644 index 0000000..b4207c7 --- /dev/null +++ b/chatclient/Data/TrayIconManager.cs @@ -0,0 +1,122 @@ +using System.Windows; +using Hardcodet.Wpf.TaskbarNotification; +using System.Windows.Controls; +using MaterialDesignThemes.Wpf; +using System.Windows.Input; +using System.Drawing; +using System.Diagnostics; + +namespace chatclient.Data +{ + public class TrayIconManager + { + private readonly TaskbarIcon _trayIcon; + private readonly Window _mainWindow; + + public TrayIconManager(Window mainWindow) + { + _mainWindow = mainWindow; + + // 创建托盘图标 + _trayIcon = new TaskbarIcon + { + Icon = new System.Drawing.Icon("resource/chat.ico"), + ToolTipText = "Material Design Application", + ContextMenu = CreateContextMenu() + }; + + // 注册事件 + _trayIcon.TrayMouseDoubleClick += TrayIcon_TrayMouseDoubleClick; + _mainWindow.Closing += MainWindow_ClosingHandler; + } + + private void MainWindow_ClosingHandler(object? sender, System.ComponentModel.CancelEventArgs e) + { + // 取消关闭操作,改为最小化到托盘 + e.Cancel = true; + _mainWindow.Hide(); + + // 显示通知 + //_trayIcon.ShowBalloonTip("Application minimized", + // "The application is running in the system tray", + // BalloonIcon.Info); + } + + private ContextMenu CreateContextMenu() + { + // 创建Material Design风格的上下文菜单 + var contextMenu = new ContextMenu + { + Style = (Style)Application.Current.Resources["MaterialTrayMenu"] + }; + + // 添加菜单项 + contextMenu.Items.Add(CreateMenuItem("Open Application", PackIconKind.WindowRestore, OpenApp_Click)); + contextMenu.Items.Add(CreateMenuItem("Settings", PackIconKind.Cog, Settings_Click)); + contextMenu.Items.Add(new Separator { Style = (Style)Application.Current.Resources["MaterialDesignLightSeparator"] }); + contextMenu.Items.Add(CreateMenuItem("Check for Updates", PackIconKind.Update, Updates_Click)); + contextMenu.Items.Add(CreateMenuItem("Help", PackIconKind.HelpCircle, Help_Click)); + contextMenu.Items.Add(new Separator { Style = (Style)Application.Current.Resources["MaterialDesignLightSeparator"] }); + contextMenu.Items.Add(CreateMenuItem("Exit", PackIconKind.Power, Exit_Click)); + + return contextMenu; + } + + private MenuItem CreateMenuItem(string header, PackIconKind iconKind, RoutedEventHandler clickHandler) + { + var menuItem = new MenuItem + { + Header = header, + Style = (Style)Application.Current.Resources["MaterialTrayMenuItem"], + Icon = new PackIcon { Kind = iconKind, Width = 20, Height = 20 } + }; + + menuItem.Click += clickHandler; + return menuItem; + } + + private void TrayIcon_TrayMouseDoubleClick(object sender, RoutedEventArgs e) + { + RestoreApplication(); + } + + private void OpenApp_Click(object sender, RoutedEventArgs e) + { + RestoreApplication(); + } + + private void RestoreApplication() + { + _mainWindow.Show(); + _mainWindow.WindowState = WindowState.Normal; + _mainWindow.Activate(); + } + + private void Settings_Click(object sender, RoutedEventArgs e) + { + // 实现设置逻辑 + } + + private void Updates_Click(object sender, RoutedEventArgs e) + { + // 实现更新检查逻辑 + } + + private void Help_Click(object sender, RoutedEventArgs e) + { + // 实现帮助逻辑 + } + + private void Exit_Click(object sender, RoutedEventArgs e) + { + // 释放托盘图标资源 + Dispose(); + Application.Current.Shutdown(); + } + + public void Dispose() + { + _trayIcon.Dispose(); + } + } +} diff --git a/chatclient/MainWindow.xaml b/chatclient/MainWindow.xaml index 094aebb..af3ebf5 100644 --- a/chatclient/MainWindow.xaml +++ b/chatclient/MainWindow.xaml @@ -8,7 +8,7 @@ xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" x:Class="chatclient.MainWindow" mc:Ignorable="d" Title="ChatWindow" Height="450" Width="800" MinHeight="240" MinWidth="380" - Style="{StaticResource MaterialDesignWindow}"> + Style="{StaticResource MaterialDesignWindow}" Closed="MainWindow_Closed" Loaded="MainWindow_Loaded"> diff --git a/chatclient/MainWindow.xaml.cs b/chatclient/MainWindow.xaml.cs index 1bf6c2e..6b2c2c2 100644 --- a/chatclient/MainWindow.xaml.cs +++ b/chatclient/MainWindow.xaml.cs @@ -56,6 +56,7 @@ namespace chatclient { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(UpdateName)); } + private TrayIconManager? _trayManager; public MainWindow() { InitializeComponent(); @@ -84,6 +85,8 @@ namespace chatclient MessageScroller.ScrollToEnd(); }), DispatcherPriority.ContextIdle); }; + //Loaded += MainWindow_Loaded; + //Closed += MainWindow_Closed; } public static void StartReceive() { @@ -325,5 +328,18 @@ namespace chatclient Task.Factory.StartNew(() => messageQueue.Enqueue(message)); } } + private void MainWindow_Loaded(object sender, RoutedEventArgs e) + { + // 初始化托盘管理器 + _trayManager = new TrayIconManager(this); + } + private void MainWindow_Closed(object sender, System.EventArgs e) + { + // 清理资源 + Client?.Shutdown(SocketShutdown.Both); + Client?.Close(); + Client?.Dispose(); + _trayManager?.Dispose(); + } } } \ No newline at end of file diff --git a/chatclient/chatclient.csproj b/chatclient/chatclient.csproj index 7f1c629..ed9a950 100644 --- a/chatclient/chatclient.csproj +++ b/chatclient/chatclient.csproj @@ -18,7 +18,9 @@ - + + PreserveNewest +