diff --git a/DMS.Application/Interfaces/IInitializeService.cs b/DMS.Application/Interfaces/IInitializeService.cs new file mode 100644 index 0000000..0ddbd56 --- /dev/null +++ b/DMS.Application/Interfaces/IInitializeService.cs @@ -0,0 +1,19 @@ +namespace DMS.Application.Services; + +public interface IInitializeService +{ + /// + /// 初始化数据库表。 + /// + void InitializeTables(); + + /// + /// 初始化数据库表索引。 + /// + void InitializeTableIndex(); + + /// + /// 初始化默认菜单。 + /// + void InitializeMenus(); +} \ No newline at end of file diff --git a/DMS.Application/Services/InitializeService.cs b/DMS.Application/Services/InitializeService.cs index eb1a4bd..36bbfa9 100644 --- a/DMS.Application/Services/InitializeService.cs +++ b/DMS.Application/Services/InitializeService.cs @@ -5,7 +5,7 @@ namespace DMS.Application.Services; /// /// 初始化服务,负责应用程序启动时的数据库和菜单初始化。 /// -public class InitializeService +public class InitializeService : IInitializeService { private readonly IInitializeRepository _repository; diff --git a/DMS.WPF/App.xaml.cs b/DMS.WPF/App.xaml.cs index 0c0812d..35f3f90 100644 --- a/DMS.WPF/App.xaml.cs +++ b/DMS.WPF/App.xaml.cs @@ -1,5 +1,8 @@ using System.Windows; +using DMS.Application.Interfaces; +using DMS.Application.Services; using DMS.Core.Enums; +using DMS.Core.Interfaces.Repositories; using DMS.Helper; using DMS.Services; using DMS.Services.Processors; @@ -10,10 +13,14 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NLog; using DMS.Extensions; +using DMS.Infrastructure.Configurations; +using DMS.Infrastructure.Data; +using DMS.Infrastructure.Repositories; using Microsoft.Extensions.Hosting; using DMS.WPF.Helper; using DMS.WPF.Services; using DMS.WPF.Services.Processors; +using IDataProcessingService = DMS.Services.IDataProcessingService; using LogLevel = Microsoft.Extensions.Logging.LogLevel; namespace DMS; @@ -73,7 +80,7 @@ public partial class App : System.Windows.Application NotificationHelper.ShowError("加载数据时发生错误,如果是连接字符串不正确,可以在设置界面更改:{exception.Message}", exception); } - MainWindow = Host.Services.GetRequiredService(); + MainWindow = Host.Services.GetRequiredService(); MainWindow.Show(); // 根据配置启动服务 @@ -123,8 +130,18 @@ public partial class App : System.Windows.Application services.AddSingleton(); services.AddSingleton(); + // 注册Core中的仓库 + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + // 注册App服务 + services.AddSingleton(); + services.AddSingleton(); + + services.AddSingleton(); // 注册视图模型 + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -136,6 +153,7 @@ public partial class App : System.Windows.Application services.AddSingleton(); services.AddScoped(); //注册View视图 + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/DMS.WPF/DMS.WPF.csproj b/DMS.WPF/DMS.WPF.csproj index 408e63b..db2515a 100644 --- a/DMS.WPF/DMS.WPF.csproj +++ b/DMS.WPF/DMS.WPF.csproj @@ -152,6 +152,7 @@ + diff --git a/DMS.WPF/Services/INavigatable.cs b/DMS.WPF/Services/INavigatable.cs new file mode 100644 index 0000000..ffd450e --- /dev/null +++ b/DMS.WPF/Services/INavigatable.cs @@ -0,0 +1,14 @@ +// 文件: DMS.WPF/Services/INavigatable.cs +namespace DMS.WPF.Services; + +/// +/// 定义了一个契约,表示ViewModel可以安全地接收导航传入的参数。 +/// +public interface INavigatable +{ + /// + /// 当导航到此ViewModel时,由导航服务调用此方法,以传递参数。 + /// + /// 从导航源传递过来的参数对象。 + Task OnNavigatedToAsync(object parameter); +} diff --git a/DMS.WPF/Services/INavigationService.cs b/DMS.WPF/Services/INavigationService.cs new file mode 100644 index 0000000..2ca3a07 --- /dev/null +++ b/DMS.WPF/Services/INavigationService.cs @@ -0,0 +1,22 @@ +// 文件: DMS.WPF/Services/INavigationService.cs +using System.Threading.Tasks; + +namespace DMS.WPF.Services; + +/// +/// 定义了应用程序的导航服务接口。 +/// +public interface INavigationService +{ + /// + /// 导航到由唯一键标识的视图,并传递一个参数。 + /// + /// 在DI容器中注册的目标视图的唯一键(通常是ViewModel的名称)。 + /// 要传递给目标ViewModel的参数。 + Task NavigateToAsync(string viewKey, object parameter = null); + + /// + /// 显示主窗口。 + /// + Task ShowMainWindowAsync(); +} diff --git a/DMS.WPF/Services/NavigationService.cs b/DMS.WPF/Services/NavigationService.cs new file mode 100644 index 0000000..3b787e9 --- /dev/null +++ b/DMS.WPF/Services/NavigationService.cs @@ -0,0 +1,72 @@ +// 文件: DMS.WPF/Services/NavigationService.cs +using DMS.WPF.ViewModels; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DMS.ViewModels; + +namespace DMS.WPF.Services; + +/// +/// INavigationService 的实现,负责解析ViewModel并处理参数传递。 +/// +public class NavigationService : INavigationService +{ + private readonly IServiceProvider _serviceProvider; + + /// + /// 构造函数。 + /// + public NavigationService(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + /// + /// 导航到指定键的视图,并传递参数。 + /// + public async Task NavigateToAsync(string viewKey, object parameter = null) + { + if (string.IsNullOrEmpty(viewKey)) + { + return; + } + + var mainViewModel = _serviceProvider.GetRequiredService(); + var viewModelType = GetViewModelTypeByKey(viewKey); + var viewModel = _serviceProvider.GetRequiredService(viewModelType) as ViewModelBase; + + if (viewModel is INavigatable navigatableViewModel) + { + await navigatableViewModel.OnNavigatedToAsync(parameter); + } + + mainViewModel.CurrentViewModel = viewModel; + } + + /// + /// 显示主窗口。 + /// + public Task ShowMainWindowAsync() + { + var mainWindow = _serviceProvider.GetRequiredService(); + mainWindow.Show(); + return Task.CompletedTask; + } + + private Type GetViewModelTypeByKey(string key) + { + return key switch + { + "HomeView" => typeof(HomeViewModel), + "DevicesView" => typeof(DevicesViewModel), + "DeviceDetailView" => typeof(DeviceDetailViewModel), + "VariableTableView" => typeof(VariableTableViewModel), + "MqttsView" => typeof(MqttsViewModel), + "MqttServerDetailView" => typeof(MqttServerDetailViewModel), + "SettingView" => typeof(SettingViewModel), + _ => throw new KeyNotFoundException($"未找到与键 '{key}' 关联的视图模型类型。请检查 NavigationService 的映射配置。") + }; + } +} diff --git a/DMS.WPF/ViewModels/SplashViewModel.cs b/DMS.WPF/ViewModels/SplashViewModel.cs new file mode 100644 index 0000000..ca13178 --- /dev/null +++ b/DMS.WPF/ViewModels/SplashViewModel.cs @@ -0,0 +1,61 @@ +// 文件: DMS.WPF/ViewModels/SplashViewModel.cs +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using DMS.Application.Interfaces; +using DMS.WPF.Services; +using System; +using System.Threading.Tasks; +using DMS.Application.Services; + +namespace DMS.WPF.ViewModels; + +/// +/// 启动加载窗口的ViewModel。 +/// +public partial class SplashViewModel : ObservableObject +{ + private readonly IServiceProvider _serviceProvider; + private readonly IInitializeService _initializeService; + + [ObservableProperty] + private string _loadingMessage = "正在加载..."; + + public SplashViewModel(IServiceProvider serviceProvider, IInitializeService initializeService) + { + _serviceProvider = serviceProvider; + _initializeService = initializeService; + } + + /// + /// 开始执行初始化任务。 + /// + public async Task InitializeAsync() + { + try + { + LoadingMessage = "正在初始化数据库..."; + _initializeService.InitializeTables(); + + LoadingMessage = "正在加载系统配置..."; + // 可以在这里添加加载配置的逻辑 + await Task.Delay(1500); // 模拟耗时 + + LoadingMessage = "正在连接后台服务..."; + // 可以在这里添加连接服务的逻辑 + await Task.Delay(1500); // 模拟耗时 + + LoadingMessage = "加载完成,正在启动主界面..."; + await Task.Delay(1500); + + // 初始化完成,显示主窗口 + var navigationService = (INavigationService)_serviceProvider.GetService(typeof(INavigationService)); + await navigationService.ShowMainWindowAsync(); + } + catch (Exception ex) + { + // 处理初始化过程中的异常 + LoadingMessage = $"初始化失败: {ex.Message}"; + // 在此可以记录日志或显示错误对话框 + } + } +} diff --git a/DMS.WPF/Views/SplashWindow.xaml b/DMS.WPF/Views/SplashWindow.xaml new file mode 100644 index 0000000..74e264d --- /dev/null +++ b/DMS.WPF/Views/SplashWindow.xaml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/DMS.WPF/Views/SplashWindow.xaml.cs b/DMS.WPF/Views/SplashWindow.xaml.cs new file mode 100644 index 0000000..bdb7e91 --- /dev/null +++ b/DMS.WPF/Views/SplashWindow.xaml.cs @@ -0,0 +1,22 @@ +// 文件: DMS.WPF/Views/SplashWindow.xaml.cs +using DMS.WPF.ViewModels; +using System.Windows; + +namespace DMS.WPF.Views; + +/// +/// SplashWindow.xaml 的交互逻辑 +/// +public partial class SplashWindow : Window +{ + public SplashWindow(SplashViewModel viewModel) + { + InitializeComponent(); + DataContext = viewModel; + Loaded += async (s, e) => + { + await viewModel.InitializeAsync(); + Close(); + }; + } +}