Ver código fonte

Merge Client and Server

Zixuan 1 dia atrás
pai
commit
b68f886be8

+ 1 - 1
EEMSMain.sln

@@ -74,7 +74,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EEMSService", "EEMSService"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EEMSServerCore", "Server\EEMSService\EEMSServerCore.csproj", "{E1F62B2E-BC79-4A21-9458-B5CA3641BD08}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBase", "Server\ServiceBase\ServiceBase.csproj", "{C1F57098-909D-4546-A1CB-660E473446AA}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EEMSUIClient", "EEMSUIClient\EEMSUIClient.csproj", "{C3C15903-D7E2-47CA-9717-A88DDC9B7F0D}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EEMSClientCore", "Server\EEMSClientCore\EEMSClientCore.csproj", "{0B0BF6F8-6BFC-4294-A9C9-014075A09392}"
 EndProject

+ 23 - 0
EEMSUIClient/App.xaml

@@ -0,0 +1,23 @@
+<prism:PrismApplication x:Class="EEMSUIClient.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:EEMSUIClient"
+             xmlns:tb="http://www.hardcodet.net/taskbar"
+             xmlns:prism="http://prismlibrary.com/"
+             ShutdownMode="OnExplicitShutdown"
+             Exit="OnExit">
+    <prism:PrismApplication.Resources>
+        <tb:TaskbarIcon x:Key="TrayIcon"
+                         IconSource="/Logo.ico"
+                         ToolTipText="EEMS Client"
+                         TrayMouseDoubleClick="TrayIcon_TrayMouseDoubleClick">
+            <tb:TaskbarIcon.ContextMenu>
+                <ContextMenu>
+                    <MenuItem Header="显示" Click="ShowMenu_Click"/>
+                    <Separator/>
+                    <MenuItem Header="退出" Click="ExitMenu_Click"/>
+                </ContextMenu>
+            </tb:TaskbarIcon.ContextMenu>
+        </tb:TaskbarIcon>
+    </prism:PrismApplication.Resources>
+</prism:PrismApplication>

+ 54 - 0
EEMSUIClient/App.xaml.cs

@@ -0,0 +1,54 @@
+using EEMSUIClient.Services;
+using EEMSUIClient.Views;
+using Hardcodet.Wpf.TaskbarNotification;
+using System.Configuration;
+using System.Data;
+using System.Windows;
+
+namespace EEMSUIClient
+{
+    /// <summary>
+    /// Interaction logic for App.xaml
+    /// </summary>
+    public partial class App : PrismApplication
+    {
+        protected override Window CreateShell()
+        {
+            return Container.Resolve<MainWindow>();
+        }
+
+        protected override void RegisterTypes(IContainerRegistry containerRegistry)
+        {
+            containerRegistry.RegisterSingleton<ITrayControl, TrayController>();
+        }
+
+        protected override void OnInitialized()
+        {
+            base.OnInitialized();
+
+            Container.Resolve<ITrayControl>().Tray = (TaskbarIcon)App.Current.FindResource("TrayIcon");
+            Container.Resolve<ITrayControl>().ShowBalloonTip();
+        }
+
+        private void TrayIcon_TrayMouseDoubleClick(object sender, RoutedEventArgs e)
+        {
+            Container.Resolve<ITrayControl>().ShowMainWindow();
+        }
+
+        private void ShowMenu_Click(object sender, RoutedEventArgs e)
+        {
+            Container.Resolve<ITrayControl>().ShowMainWindow();
+        }
+
+        private void ExitMenu_Click(object sender, RoutedEventArgs e)
+        {
+            Container.Resolve<ITrayControl>().Exit();
+        }
+
+        private void OnExit(object sender, ExitEventArgs e)
+        {
+            Container.Resolve<ITrayControl>().Dispose();
+        }
+    }
+
+}

+ 10 - 0
EEMSUIClient/AssemblyInfo.cs

@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None,            //where theme specific resource dictionaries are located
+                                                //(used if a resource is not found in the page,
+                                                // or application resource dictionaries)
+    ResourceDictionaryLocation.SourceAssembly   //where the generic resource dictionary is located
+                                                //(used if a resource is not found in the page,
+                                                // app, or any theme specific resource dictionaries)
+)]

+ 20 - 0
EEMSUIClient/EEMSUIClient.csproj

@@ -0,0 +1,20 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <Nullable>enable</Nullable>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <UseWPF>true</UseWPF>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Prism.DryIoc" />
+    <PackageReference Include="CommunityToolkit.Mvvm" />
+    <PackageReference Include="Hardcodet.NotifyIcon.Wpf" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Resource Include="Logo.ico" />
+  </ItemGroup>
+</Project>

BIN
EEMSUIClient/Logo.ico


+ 19 - 0
EEMSUIClient/Services/ITrayControl.cs

@@ -0,0 +1,19 @@
+using Hardcodet.Wpf.TaskbarNotification;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EEMSUIClient.Services
+{
+    public interface ITrayControl : IDisposable
+    {
+        TaskbarIcon? Tray { set; }
+        bool IsExiting { get; }
+        void HideToTray();
+        void ShowMainWindow();
+        void Exit();
+        void ShowBalloonTip();
+    }
+}

+ 93 - 0
EEMSUIClient/Services/TrayController.cs

@@ -0,0 +1,93 @@
+using EEMSUIClient.Views;
+using Hardcodet.Wpf.TaskbarNotification;
+using System.Windows;
+
+namespace EEMSUIClient.Services
+{
+    public sealed class TrayController : ITrayControl
+    {
+        private TaskbarIcon? _tray;
+
+        private bool disposedValue;
+
+        public TaskbarIcon? Tray
+        {
+            set
+            {
+                ObjectDisposedException.ThrowIf(disposedValue, nameof(_tray));
+                _tray = value;
+            }
+        }
+
+        public bool IsExiting { get; private set; }
+
+        public void HideToTray()
+        {
+            var mainWindow = (MainWindow)Application.Current.MainWindow;
+            mainWindow.ShowInTaskbar = false;
+            mainWindow.Hide();
+        }
+
+        public void ShowMainWindow()
+        {
+            var mainWindow = (MainWindow)Application.Current.MainWindow;
+            if (!mainWindow.IsVisible)
+            {
+                mainWindow.Show();
+            }
+            mainWindow.WindowState = WindowState.Normal;
+            mainWindow.ShowInTaskbar = true;
+            mainWindow.Activate();
+            mainWindow.Topmost = true;
+            mainWindow.Topmost = false;
+            mainWindow.Focus();
+        }
+
+        public void Exit()
+        {
+            IsExiting = true;
+            Application.Current.MainWindow?.Close();
+            Application.Current.Shutdown();
+        }
+
+        public void ShowBalloonTip()
+        {
+            _tray?.ShowBalloonTip("EEMS Client", "服务正在后台运行...", BalloonIcon.Info);
+        }
+
+        private void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+                    // TODO: dispose managed state (managed objects)
+                    if (_tray != null)
+                    {
+                        _tray.Visibility = Visibility.Hidden;
+                        _tray.Dispose();
+                        _tray = null;
+                    }
+                }
+
+                // TODO: free unmanaged resources (unmanaged objects) and override finalizer
+                // TODO: set large fields to null
+                disposedValue = true;
+            }
+        }
+
+        // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
+        // ~TrayController()
+        // {
+        //     // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+        //     Dispose(disposing: false);
+        // }
+
+        public void Dispose()
+        {
+            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+    }
+}

+ 19 - 0
EEMSUIClient/ViewModels/MainWindowViewModel.cs

@@ -0,0 +1,19 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using EEMSUIClient.Services;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EEMSUIClient.ViewModels
+{
+    public partial class MainWindowViewModel : ObservableObject
+    {
+        public MainWindowViewModel()
+        {
+
+        }
+    }
+}

+ 15 - 0
EEMSUIClient/Views/MainWindow.xaml

@@ -0,0 +1,15 @@
+<Window x:Class="EEMSUIClient.Views.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:EEMSUIClient.Views"
+        xmlns:prism="http://prismlibrary.com/"
+        prism:ViewModelLocator.AutoWireViewModel="True"
+        mc:Ignorable="d"
+        Title="MainWindow" Height="450" Width="800"
+        WindowStartupLocation="CenterScreen" ResizeMode="NoResize" WindowStyle="SingleBorderWindow">
+    <Grid>
+        
+    </Grid>
+</Window>

+ 30 - 0
EEMSUIClient/Views/MainWindow.xaml.cs

@@ -0,0 +1,30 @@
+using EEMSUIClient.Services;
+using System.Windows;
+
+namespace EEMSUIClient.Views
+{
+    /// <summary>
+    /// Interaction logic for MainWindow.xaml
+    /// </summary>
+    public partial class MainWindow : Window
+    {
+        private readonly ITrayControl _trayController;
+
+        public MainWindow(ITrayControl trayController)
+        {
+            InitializeComponent();
+
+            _trayController = trayController;
+            this.Closing += MainWindow_Closing;
+        }
+
+        private void MainWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
+        {
+            if(!_trayController.IsExiting)
+            {
+                e.Cancel = true;
+                _trayController.HideToTray();
+            }
+        }
+    }
+}