using Microsoft.Extensions.Logging; using MyAvaloniaApp.Services; using ReactiveUI; using System; using System.Collections.ObjectModel; using System.Linq; using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; namespace MyAvaloniaApp.ViewModels; /// /// 主窗口的 ViewModel /// public class MainWindowViewModel : ReactiveObject { private string _title = "My Avalonia App - 导航栏 + 标签页"; private string _headerTitle = "系统管理平台"; private string _headerSubtitle = "欢迎使用现代化管理界面"; private ObservableCollection _navigationItems = new(); private ObservableCollection _tabs = new(); private NavigationItem? _selectedNavigationItem; private TabItem? _selectedTab; private readonly ILogger? _logger; private readonly IDataService? _dataService; private readonly IResourceService? _resourceService; public string Title { get => _title; set => this.RaiseAndSetIfChanged(ref _title, value); } public string HeaderTitle { get => _headerTitle; set => this.RaiseAndSetIfChanged(ref _headerTitle, value); } public string HeaderSubtitle { get => _headerSubtitle; set => this.RaiseAndSetIfChanged(ref _headerSubtitle, value); } public ObservableCollection NavigationItems { get => _navigationItems; set => this.RaiseAndSetIfChanged(ref _navigationItems, value); } public ObservableCollection Tabs { get => _tabs; set => this.RaiseAndSetIfChanged(ref _tabs, value); } public NavigationItem? SelectedNavigationItem { get => _selectedNavigationItem; set => this.RaiseAndSetIfChanged(ref _selectedNavigationItem, value); } public TabItem? SelectedTab { get => _selectedTab; set => this.RaiseAndSetIfChanged(ref _selectedTab, value); } // 响应式命令 public ReactiveCommand NavigateCommand { get; } public ReactiveCommand CloseTabCommand { get; } public ReactiveCommand SelectTabCommand { get; } public MainWindowViewModel(ILogger? logger = null, IDataService? dataService = null, IResourceService? resourceService = null) { _logger = logger; _dataService = dataService; _resourceService = resourceService; _logger?.LogInformation("MainWindowViewModel 已创建"); // 初始化导航项 InitializeNavigationItems(); // 初始化标签页 InitializeTabs(); // 创建导航命令 NavigateCommand = ReactiveCommand.Create(NavigateToPage); // 创建关闭标签页命令 CloseTabCommand = ReactiveCommand.Create(CloseTab); // 创建选择标签页命令 SelectTabCommand = ReactiveCommand.Create(SelectTab); // 监听导航项选择变化 this.WhenAnyValue(x => x.SelectedNavigationItem) .Where(item => item != null) .Subscribe(item => _logger?.LogInformation("导航到: {Title}", item!.Title)); // 监听标签页选择变化 this.WhenAnyValue(x => x.SelectedTab) .Where(tab => tab != null) .Subscribe(tab => _logger?.LogInformation("切换到标签页: {Title}", tab!.Title)); } private void InitializeNavigationItems() { _navigationItems = new ObservableCollection { new NavigationItem { Id = "dashboard", Title = _resourceService?.GetString("NavDashboard") ?? "仪表板", IconType = HeroIconsAvalonia.Enums.IconType.Home, Content = new Views.Pages.DashboardPageView { DataContext = new Pages.DashboardPageViewModel() } }, new NavigationItem { Id = "users", Title = _resourceService?.GetString("NavUsers") ?? "用户管理", IconType = HeroIconsAvalonia.Enums.IconType.Users, Children = new ObservableCollection { new NavigationItem { Id = "users-list", Title = "用户列表", IconType = HeroIconsAvalonia.Enums.IconType.UserGroup, Content = new Views.Pages.UsersPageView { DataContext = new Pages.UsersPageViewModel() } }, new NavigationItem { Id = "users-roles", Title = "角色管理", IconType = HeroIconsAvalonia.Enums.IconType.ShieldCheck, Content = new Views.Pages.UsersPageView { DataContext = new Pages.UsersPageViewModel() } }, new NavigationItem { Id = "users-permissions", Title = "权限设置", IconType = HeroIconsAvalonia.Enums.IconType.Key, Content = new Views.Pages.UsersPageView { DataContext = new Pages.UsersPageViewModel() } } } }, new NavigationItem { Id = "settings", Title = _resourceService?.GetString("NavSettings") ?? "系统设置", IconType = HeroIconsAvalonia.Enums.IconType.Cog6Tooth, Children = new ObservableCollection { new NavigationItem { Id = "settings-general", Title = "常规设置", IconType = HeroIconsAvalonia.Enums.IconType.Cog, Content = new Views.Pages.SettingsPageView { DataContext = new Pages.SettingsPageViewModel() } }, new NavigationItem { Id = "settings-security", Title = "安全设置", IconType = HeroIconsAvalonia.Enums.IconType.LockClosed, Content = new Views.Pages.SettingsPageView { DataContext = new Pages.SettingsPageViewModel() } }, new NavigationItem { Id = "settings-backup", Title = "备份恢复", IconType = HeroIconsAvalonia.Enums.IconType.CloudArrowUp, Content = new Views.Pages.SettingsPageView { DataContext = new Pages.SettingsPageViewModel() } } } }, new NavigationItem { Id = "reports", Title = _resourceService?.GetString("NavReports") ?? "报表统计", IconType = HeroIconsAvalonia.Enums.IconType.ChartBar, Content = new Views.Pages.ReportsPageView { DataContext = new Pages.ReportsPageViewModel() } }, new NavigationItem { Id = "help", Title = _resourceService?.GetString("NavHelp") ?? "帮助中心", IconType = HeroIconsAvalonia.Enums.IconType.QuestionMarkCircle, Content = new Views.Pages.HelpPageView { DataContext = new Pages.HelpPageViewModel() } }, new NavigationItem { Id = "icons", Title = _resourceService?.GetString("NavIcons") ?? "图标库", IconType = HeroIconsAvalonia.Enums.IconType.Sparkles, Content = new Views.Pages.IconsPageView { DataContext = new Pages.IconsPageViewModel() } } }; // 默认选中第一个导航项 if (_navigationItems.Count > 0) { _navigationItems[0].IsSelected = true; SelectedNavigationItem = _navigationItems[0]; } } private void InitializeTabs() { _tabs = new ObservableCollection(); // 默认添加仪表板标签页 if (_navigationItems.Count > 0) { var dashboardNav = _navigationItems.FirstOrDefault(x => x.Id == "dashboard"); if (dashboardNav != null) { var dashboardTab = new TabItem { Id = "dashboard", Title = _resourceService?.GetString("PageDashboard") ?? "仪表板", IconType = HeroIconsAvalonia.Enums.IconType.Home, Content = dashboardNav.Content, IsSelected = true, CanClose = false }; _tabs.Add(dashboardTab); SelectedTab = dashboardTab; } } } private void NavigateToPage(NavigationItem navigationItem) { if (navigationItem == null) return; // 检查是否是子级菜单项 bool isChildItem = _navigationItems.Any(parent => parent.Children.Contains(navigationItem)); if (isChildItem) { // 子级菜单项:只选中当前项,不影响父级菜单的展开状态 // 取消所有导航项的选中状态 foreach (var item in _navigationItems) { item.IsSelected = false; foreach (var child in item.Children) { child.IsSelected = false; } } // 设置当前子项为选中状态 navigationItem.IsSelected = true; SelectedNavigationItem = navigationItem; // 创建标签页 CreateTabForNavigationItem(navigationItem); _logger?.LogInformation("导航到子页面: {Title}", navigationItem.Title); } else if (navigationItem.HasChildren) { // 父级菜单项:处理展开/收起逻辑 // 检查是否已经展开 if (navigationItem.IsExpanded) { // 如果已经展开,则收起 navigationItem.IsExpanded = false; // 取消所有导航项的选中状态 foreach (var item in _navigationItems) { item.IsSelected = false; foreach (var child in item.Children) { child.IsSelected = false; } } // 清除 SelectedNavigationItem SelectedNavigationItem = null; _logger?.LogInformation("收起导航项: {Title}", navigationItem.Title); } else { // 如果未展开,则展开并选中第一个子项 // 先收起其他所有展开的父级导航项 foreach (var item in _navigationItems) { if (item != navigationItem && item.HasChildren) { item.IsExpanded = false; item.IsSelected = false; foreach (var child in item.Children) { child.IsSelected = false; } } } // 展开当前导航项 navigationItem.IsExpanded = true; // 选中第一个子项 if (navigationItem.Children.Count > 0) { var firstChild = navigationItem.Children[0]; firstChild.IsSelected = true; SelectedNavigationItem = firstChild; // 为第一个子项创建标签页 CreateTabForNavigationItem(firstChild); } _logger?.LogInformation("展开导航项: {Title}", navigationItem.Title); } } else { // 无子项的父级导航项,直接选中 // 先收起所有展开的父级导航项 foreach (var item in _navigationItems) { if (item.HasChildren) { item.IsExpanded = false; } item.IsSelected = false; foreach (var child in item.Children) { child.IsSelected = false; } } // 设置当前导航项为选中状态 navigationItem.IsSelected = true; SelectedNavigationItem = navigationItem; // 创建标签页 CreateTabForNavigationItem(navigationItem); _logger?.LogInformation("导航到页面: {Title}", navigationItem.Title); } } private void CreateTabForNavigationItem(NavigationItem navigationItem) { // 检查是否已经存在对应的标签页 var existingTab = _tabs.FirstOrDefault(t => t.Id == navigationItem.Id); if (existingTab != null) { // 如果标签页已存在,选中它 foreach (var tab in _tabs) { tab.IsSelected = false; } existingTab.IsSelected = true; SelectedTab = existingTab; } else { // 创建新的标签页 var newTab = new TabItem { Id = navigationItem.Id, Title = navigationItem.Title, IconType = navigationItem.IconType, Content = navigationItem.Content, IsSelected = true, CanClose = navigationItem.Id != "dashboard" // 仪表板标签页不能关闭 }; // 取消其他标签页的选中状态 foreach (var tab in _tabs) { tab.IsSelected = false; } _tabs.Add(newTab); SelectedTab = newTab; } } private void SelectTab(TabItem tab) { if (tab == null) return; // 取消所有标签页的选中状态 foreach (var t in _tabs) { t.IsSelected = false; } // 设置当前标签页为选中状态 tab.IsSelected = true; SelectedTab = tab; _logger?.LogInformation("选择标签页: {Title}", tab.Title); } private void CloseTab(TabItem tab) { if (tab == null || !tab.CanClose) return; var tabIndex = _tabs.IndexOf(tab); _tabs.Remove(tab); // 如果关闭的是当前选中的标签页,需要选择其他标签页 if (tab.IsSelected && _tabs.Count > 0) { var newSelectedIndex = Math.Min(tabIndex, _tabs.Count - 1); _tabs[newSelectedIndex].IsSelected = true; SelectedTab = _tabs[newSelectedIndex]; } _logger?.LogInformation("关闭标签页: {Title}", tab.Title); } }