diff --git a/src/UI/WPF/LogisticsControlPanel.xaml.cs b/src/UI/WPF/LogisticsControlPanel.xaml.cs index 046e335..f9dab2b 100644 --- a/src/UI/WPF/LogisticsControlPanel.xaml.cs +++ b/src/UI/WPF/LogisticsControlPanel.xaml.cs @@ -33,7 +33,7 @@ namespace NavisworksTransport.UI.WPF // 创建并设置ViewModel ViewModel = new LogisticsControlViewModel(); - SystemManagementViewModel = new SystemManagementViewModel(); + SystemManagementViewModel = new SystemManagementViewModel(ViewModel); // 传递主ViewModel引用 DataContext = ViewModel; // 为SystemManagementView设置独立的DataContext @@ -155,10 +155,22 @@ namespace NavisworksTransport.UI.WPF { try { + // 重新创建AnimationControlView,传入主ViewModel引用 + var newAnimationControlView = new AnimationControlView(ViewModel); + + // 替换XAML中的AnimationControlView + if (AnimationControlTab?.Content is Border animationControlBorder) + { + animationControlBorder.Child = newAnimationControlView; + + // 更新引用 + AnimationControlView = newAnimationControlView; + } + if (AnimationControlView?.ViewModel != null) { // 动画控制视图现在通过PathEditingView获取路径信息 - LogManager.Info("AnimationControlView初始化完成"); + LogManager.Info("AnimationControlView初始化完成 - 支持统一状态栏"); } } catch (Exception ex) @@ -174,12 +186,24 @@ namespace NavisworksTransport.UI.WPF { try { + // 重新创建PathEditingView,传入主ViewModel引用 + var newPathEditingView = new PathEditingView(ViewModel); + + // 替换XAML中的PathEditingView + if (PathEditingTab?.Content is Border pathEditingBorder) + { + pathEditingBorder.Child = newPathEditingView; + + // 更新引用 + PathEditingView = newPathEditingView; + } + if (PathEditingView?.ViewModel != null) { // 将PathPlanningManager传递给PathEditingView PathEditingView.ViewModel.PathPlanningManager = _pathPlanningManager; - LogManager.Info("PathEditingView初始化完成"); + LogManager.Info("PathEditingView初始化完成 - 支持统一状态栏"); } } catch (Exception ex) diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index 6295daa..50ef64c 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -72,6 +72,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels private readonly NavisworksTransport.Core.Animation.LogisticsAnimationManager _logisticsAnimationManager; private readonly ClashDetectiveIntegration _clashIntegration; private readonly UIStateManager _uiStateManager; + private readonly LogisticsControlViewModel _mainViewModel; // 动画参数相关字段 private ObservableCollection _availableFrameRates; @@ -81,14 +82,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels private bool _canStartAnimation = true; private bool _canPauseAnimation = false; private bool _canStopAnimation = false; - private string _animationStatus = "就绪"; private double _animationProgress = 0.0; private string _startAnimationButtonText = "开始动画"; // 碰撞检测相关字段 private bool _hasCollisionResults = false; - private string _collisionStatus = "就绪"; - private string _collisionSummary = "尚未运行碰撞检测"; // 碰撞检测参数字段 private double _collisionDetectionAccuracy = 0.1; // 检测精度(米) @@ -110,7 +108,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels private string _selectedAnimatedObjectName = "未选择移动物体"; private bool _hasSelectedAnimatedObject = false; private bool _canGenerateAnimation = false; - private string _generationStatus = "就绪"; #endregion @@ -182,14 +179,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _canStopAnimation, value); } - /// - /// 动画状态 - /// - public string AnimationStatus - { - get => _animationStatus; - set => SetProperty(ref _animationStatus, value); - } /// /// 动画进度 @@ -219,23 +208,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _hasCollisionResults, value); } - /// - /// 碰撞检测状态 - /// - public string CollisionStatus - { - get => _collisionStatus; - set => SetProperty(ref _collisionStatus, value); - } - /// - /// 碰撞检测摘要 - /// - public string CollisionSummary - { - get => _collisionSummary; - set => SetProperty(ref _collisionSummary, value); - } /// /// 碰撞检测精度(米) @@ -339,6 +312,22 @@ namespace NavisworksTransport.UI.WPF.ViewModels UpdateAnimatedObjectInfo(); UpdateCanGenerateAnimation(); + // 移动物体改变时清除已生成的动画(如果有的话) + if (_pathAnimationManager != null && + (_pathAnimationManager.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Ready || + _pathAnimationManager.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Finished)) + { + try + { + _pathAnimationManager.StopAnimation(); // 这会将状态设置为Stopped,需要重新生成动画 + LogManager.Info("移动物体更改,已清除之前生成的动画"); + } + catch (Exception ex) + { + LogManager.Warning($"清除之前动画时出现警告: {ex.Message}"); + } + } + // ✨ 新功能:动画对象选择时预计算排除列表(线程安全版本) _ = PrecomputeCollisionExclusionsAsync(value); } @@ -371,14 +360,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _canGenerateAnimation, value); } - /// - /// 生成状态 - /// - public string GenerationStatus - { - get => _generationStatus; - set => SetProperty(ref _generationStatus, value); - } #endregion @@ -434,6 +415,52 @@ namespace NavisworksTransport.UI.WPF.ViewModels } } + /// + /// 带主ViewModel参数的构造函数,支持统一状态栏 + /// + /// 主ViewModel,用于统一状态栏 + public AnimationControlViewModel(LogisticsControlViewModel mainViewModel) : base() + { + try + { + // 保存主ViewModel引用 + _mainViewModel = mainViewModel; + + // 初始化管理器 + _pathAnimationManager = new NavisworksTransport.Core.Animation.PathAnimationManager(); + _logisticsAnimationManager = new NavisworksTransport.Core.Animation.LogisticsAnimationManager(); + _clashIntegration = ClashDetectiveIntegration.Instance; + _uiStateManager = UIStateManager.Instance; + + // 订阅PathAnimationManager事件 + _pathAnimationManager.ProgressChanged += OnAnimationProgressChanged; + _pathAnimationManager.StateChanged += OnAnimationStateChanged; + + // 初始化集合 + AvailableFrameRates = new ThreadSafeObservableCollection(); + + // 初始化设置 + InitializeAnimationSettings(); + + // 初始化命令 + InitializeCommands(); + + // 初始化碰撞检测集成 + InitializeClashIntegration(); + + // 初始化防抖定时器 + InitializeParameterUpdateTimer(); + + LogManager.Info("AnimationControlViewModel初始化完成 - 支持统一状态栏"); + } + catch (Exception ex) + { + LogManager.Error($"AnimationControlViewModel初始化失败: {ex.Message}", ex); + UpdateMainStatus("初始化失败,请检查日志"); + throw; + } + } + #endregion #region 初始化方法 @@ -464,8 +491,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 初始化碰撞检测状态 HasCollisionResults = false; - CollisionStatus = "就绪"; - CollisionSummary = "尚未运行碰撞检测"; + UpdateMainStatus("碰撞检测就绪"); // 初始化碰撞检测参数 CollisionDetectionAccuracy = 0.1; // 0.1米 @@ -529,7 +555,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await _uiStateManager.ExecuteUIUpdateAsync(() => { - AnimationStatus = "请先选择包含至少2个点的路径"; + UpdateMainStatus("请先选择包含至少2个点的路径"); }); return; } @@ -549,7 +575,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Warning("动画已在播放中"); await _uiStateManager.ExecuteUIUpdateAsync(() => { - AnimationStatus = "动画已在播放中"; + UpdateMainStatus("动画已在播放中"); CanStartAnimation = true; CanPauseAnimation = false; CanStopAnimation = false; @@ -577,7 +603,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await _uiStateManager.ExecuteUIUpdateAsync(() => { - AnimationStatus = $"开始动画出错: {ex.Message}"; + UpdateMainStatus($"开始动画出错: {ex.Message}"); LogManager.Error($"开始动画异常: {ex.Message}", ex); // 恢复按钮状态 @@ -608,7 +634,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 错误时手动恢复UI状态 await _uiStateManager.ExecuteUIUpdateAsync(() => { - AnimationStatus = "暂停动画失败"; + UpdateMainStatus("暂停动画失败"); }); } } @@ -622,7 +648,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await _uiStateManager.ExecuteUIUpdateAsync(() => { - AnimationStatus = "动画状态: 已停止"; + UpdateMainStatus("动画已停止"); AnimationProgress = 0; CurrentAnimationTime = 0.0; @@ -652,7 +678,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await _uiStateManager.ExecuteUIUpdateAsync(() => { - CollisionStatus = "尚无碰撞检测结果可查看"; + UpdateMainStatus("尚无碰撞检测结果可查看"); }); return; } @@ -661,7 +687,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await _uiStateManager.ExecuteUIUpdateAsync(() => { - CollisionStatus = "正在生成碰撞报告..."; + UpdateMainStatus("正在生成碰撞报告...", -1, true); }); LogManager.Info("开始生成碰撞检测详细报告"); @@ -687,7 +713,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels await _uiStateManager.ExecuteUIUpdateAsync(() => { - CollisionStatus = "碰撞报告已生成"; + UpdateMainStatus("碰撞报告已生成"); LogManager.Info("碰撞报告生成完成并已显示"); }); } @@ -695,7 +721,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await _uiStateManager.ExecuteUIUpdateAsync(() => { - CollisionStatus = "生成碰撞报告失败"; + UpdateMainStatus("生成碰撞报告失败"); }); } } @@ -703,7 +729,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await _uiStateManager.ExecuteUIUpdateAsync(() => { - CollisionStatus = "查看碰撞报告出错"; + UpdateMainStatus("查看碰撞报告出错"); }); LogManager.Error($"查看碰撞报告异常: {ex.Message}", ex); } @@ -720,21 +746,37 @@ namespace NavisworksTransport.UI.WPF.ViewModels { CurrentPathRoute = pathRoute; + // 路径改变时清除已生成的动画(如果有的话) + if (_pathAnimationManager != null && + (_pathAnimationManager.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Ready || + _pathAnimationManager.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Finished)) + { + try + { + _pathAnimationManager.StopAnimation(); // 这会将状态设置为Stopped,需要重新生成动画 + LogManager.Info("路径更改,已清除之前生成的动画"); + } + catch (Exception ex) + { + LogManager.Warning($"清除之前动画时出现警告: {ex.Message}"); + } + } + // 使用新的统一按钮状态更新方法 UpdateAnimationButtonStates(); // 更新碰撞状态 if (pathRoute == null) { - CollisionStatus = "请选择路径"; + UpdateMainStatus("请选择路径"); } else if (pathRoute.Points.Count < 2) { - CollisionStatus = "路径点数不足"; + UpdateMainStatus("路径点数不足"); } else { - CollisionStatus = "就绪"; + UpdateMainStatus("碰撞检测就绪"); } LogManager.Info($"AnimationControlViewModel当前路径更新: {pathRoute?.Name ?? "无"}, 点数: {pathRoute?.Points.Count ?? 0}"); @@ -771,21 +813,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels CanPauseAnimation = true; CanStopAnimation = true; StartAnimationButtonText = "开始动画"; // 播放中时按钮显示为灰色的"开始动画" - AnimationStatus = "动画状态: 播放中"; + UpdateMainStatus("动画播放中"); break; case NavisworksTransport.Core.Animation.AnimationState.Paused: CanStartAnimation = true; // 暂停状态下可以继续 CanPauseAnimation = false; CanStopAnimation = true; StartAnimationButtonText = "继续播放"; // 暂停状态下显示"继续播放" - AnimationStatus = "动画状态: 已暂停"; + UpdateMainStatus("动画已暂停"); break; case NavisworksTransport.Core.Animation.AnimationState.Finished: CanStartAnimation = true; CanPauseAnimation = false; CanStopAnimation = false; StartAnimationButtonText = "开始动画"; // 完成后恢复"开始动画" - AnimationStatus = "动画状态: 已完成"; + UpdateMainStatus("动画已完成"); // 动画完成后更新碰撞检测状态 UpdateCollisionStatusAfterAnimation(); break; @@ -794,11 +836,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels CanPauseAnimation = false; CanStopAnimation = false; StartAnimationButtonText = "开始动画"; // 停止后恢复"开始动画" - AnimationStatus = "动画状态: 已停止"; + UpdateMainStatus("动画已停止"); break; default: StartAnimationButtonText = "开始动画"; - AnimationStatus = $"动画状态: {state}"; + UpdateMainStatus($"动画状态: {state}"); break; } })); @@ -813,9 +855,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels await _uiStateManager.ExecuteUIUpdateAsync(() => { HasCollisionResults = e.Results.Count > 0; - CollisionSummary = e.Results.Count > 0 + var summary = e.Results.Count > 0 ? $"发现 {e.Results.Count} 个碰撞点" : "未发现碰撞"; + UpdateMainStatus(summary); }); } @@ -834,14 +877,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (selectedItems.Count == 0) { - GenerationStatus = "请先在Navisworks中选择一个物体"; + UpdateMainStatus("请先在Navisworks中选择一个物体"); LogManager.Warning("用户未选择任何物体"); return; } if (selectedItems.Count > 1) { - GenerationStatus = "请只选择一个物体作为移动对象"; + UpdateMainStatus("请只选择一个物体作为移动对象"); LogManager.Warning($"用户选择了{selectedItems.Count}个物体,需要只选择一个"); return; } @@ -853,7 +896,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (!hasAnyGeometry) { - GenerationStatus = "选中的项目及其子项都不包含几何体,请选择其他物体"; + UpdateMainStatus("选中的项目及其子项都不包含几何体,请选择其他物体"); LogManager.Warning("选中的项目及其子项都不包含几何体"); return; } @@ -862,13 +905,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 设置选中的移动物体 SelectedAnimatedObject = selectedItem; - GenerationStatus = "移动物体选择成功"; + UpdateMainStatus("移动物体选择成功"); LogManager.Info($"移动物体选择成功: {SelectedAnimatedObject.DisplayName}"); } catch (Exception ex) { - GenerationStatus = "选择移动物体失败"; + UpdateMainStatus("选择移动物体失败"); LogManager.Error($"选择移动物体时发生错误: {ex.Message}"); } } @@ -897,6 +940,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels } } + // 清除PathAnimationManager中的动画数据,将状态重置为Idle + if (_pathAnimationManager != null) + { + try + { + // 重置动画对象到原始位置并清除动画数据 + _pathAnimationManager.ResetAnimation(); + LogManager.Info("已清除PathAnimationManager中的动画数据"); + } + catch (Exception resetEx) + { + LogManager.Warning($"重置PathAnimationManager时出现警告: {resetEx.Message}"); + } + } + // 如果有选中的物体,则恢复到原始位置 if (SelectedAnimatedObject != null) { @@ -910,18 +968,18 @@ namespace NavisworksTransport.UI.WPF.ViewModels doc.Models.ResetPermanentTransform(modelItems); LogManager.Info($"物体 '{SelectedAnimatedObject.DisplayName}' 已成功恢复到原始位置"); - GenerationStatus = "已清除移动物体选择并恢复到原始位置"; + UpdateMainStatus("已清除移动物体选择并恢复到原始位置"); } catch (Exception restoreEx) { LogManager.Error($"恢复物体到原始位置时发生错误: {restoreEx.Message}"); - GenerationStatus = $"已清除物体选择,但恢复位置失败: {restoreEx.Message}"; + UpdateMainStatus($"已清除物体选择,但恢复位置失败: {restoreEx.Message}"); } } else { LogManager.Info("没有选中的物体需要清除"); - GenerationStatus = "已清除移动物体选择"; + UpdateMainStatus("已清除移动物体选择"); } // 清理选择状态 @@ -933,8 +991,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 清理碰撞检测结果 HasCollisionResults = false; - CollisionStatus = "就绪"; - CollisionSummary = "尚未运行碰撞检测"; + UpdateMainStatus("碰撞检测重置"); // 更新按钮状态 - 清除动画后应该重新评估按钮状态 UpdateAnimationButtonStates(); @@ -947,7 +1004,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"清除移动物体选择时发生错误: {ex.Message}"); - GenerationStatus = $"清除失败: {ex.Message}"; + UpdateMainStatus($"清除失败: {ex.Message}"); } } @@ -970,7 +1027,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 在UI线程中更新开始状态 await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() => { - GenerationStatus = "正在分析动画对象..."; + UpdateMainStatus("正在分析动画对象...", -1, true); })); // 在UI线程中执行Navisworks API操作(线程安全) @@ -991,12 +1048,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (success) { var cacheStats = _logisticsAnimationManager.GetCacheStats(); - GenerationStatus = $"动画对象分析完成"; + UpdateMainStatus("动画对象分析完成"); LogManager.Info($"[缓存预计算] 预计算成功 - {cacheStats}"); } else { - GenerationStatus = "动画对象分析失败,将使用实时计算"; + UpdateMainStatus("动画对象分析失败,将使用实时计算"); LogManager.Warning("[缓存预计算] 预计算失败,碰撞检测将使用实时计算模式"); } })); @@ -1006,7 +1063,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Error($"[缓存预计算] 异步预计算过程异常: {ex.Message}", ex); await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() => { - GenerationStatus = "动画对象分析异常"; + UpdateMainStatus("动画对象分析异常"); })); } } @@ -1020,16 +1077,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels { if (!CanGenerateAnimation) { - GenerationStatus = "无法生成动画:缺少必要条件"; + UpdateMainStatus("无法生成动画:缺少必要条件"); LogManager.Warning("尝试生成动画但条件不满足"); return; } - GenerationStatus = "正在生成动画..."; + UpdateMainStatus("正在生成动画...", -1, true); LogManager.Info("开始生成动画"); // 🔥 新增:在生成动画阶段构建碰撞检测缓存 - GenerationStatus = "正在构建碰撞检测缓存..."; + UpdateMainStatus("正在构建碰撞检测缓存...", -1, true); LogManager.Info("[动画生成] 开始构建碰撞检测缓存"); var cacheStartTime = DateTime.Now; @@ -1038,10 +1095,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 构建全局缓存(与具体移动物体无关) ClashDetectiveIntegration.ClearAllCaches(); - GenerationStatus = "正在缓存几何对象列表..."; + UpdateMainStatus("正在缓存几何对象列表...", -1, true); ClashDetectiveIntegration.BuildAllGeometryItemsCache(); - GenerationStatus = "正在缓存通道对象..."; + UpdateMainStatus("正在缓存通道对象...", -1, true); var clashIntegration = ClashDetectiveIntegration.Instance; clashIntegration.BuildChannelObjectsCache(); @@ -1049,7 +1106,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Info($"[动画生成] 碰撞检测缓存构建完成,耗时: {cacheElapsed:F1}ms"); // 构建特定于动画对象的缓存 - GenerationStatus = "正在分析动画对象..."; + UpdateMainStatus("正在分析动画对象...", -1, true); var success = _logisticsAnimationManager.PrecomputeCollisionExclusions(SelectedAnimatedObject); if (!success) @@ -1063,17 +1120,17 @@ namespace NavisworksTransport.UI.WPF.ViewModels } // 原有的动画生成逻辑 - GenerationStatus = "正在生成路径动画..."; + UpdateMainStatus("正在生成路径动画...", -1, true); // 将PathRouteViewModel的点转换为Point3D列表 var pathPoints = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList(); - // 使用PathAnimationManager设置物体动画(真正的物体移动动画) - _pathAnimationManager.SetupAnimation(SelectedAnimatedObject, pathPoints, AnimationDuration); + // 使用PathAnimationManager创建物体动画(真正的物体移动动画,会设置状态为Ready) + _pathAnimationManager.CreateAnimation(SelectedAnimatedObject, pathPoints, AnimationDuration); // 更新状态 - 使用新的按钮状态更新方法 UpdateAnimationButtonStates(); - GenerationStatus = "动画生成成功"; + UpdateMainStatus("动画生成成功"); var totalElapsed = (DateTime.Now - cacheStartTime).TotalMilliseconds; LogManager.Info($"[动画生成] 动画生成完成,总耗时: {totalElapsed:F1}ms"); @@ -1081,8 +1138,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels } catch (Exception ex) { - GenerationStatus = "动画生成失败"; - AnimationStatus = "动画生成失败"; + UpdateMainStatus("动画生成失败"); LogManager.Error($"生成动画时发生错误: {ex.Message}"); LogManager.Error($"动画生成失败,详细错误信息:{ex}"); @@ -1138,19 +1194,19 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (!hasObject && !hasPath) { - GenerationStatus = "请选择移动物体和动画路径"; + UpdateMainStatus("请选择移动物体和动画路径"); } else if (!hasObject) { - GenerationStatus = "请选择移动物体"; + UpdateMainStatus("请选择移动物体"); } else if (!hasPath) { - GenerationStatus = "请选择有效的动画路径"; + UpdateMainStatus("请选择有效的动画路径"); } else { - GenerationStatus = "可以生成动画"; + UpdateMainStatus("可以生成动画"); } // 同时更新动画按钮状态,因为对象或路径的变化会影响"开始动画"按钮的可用性 @@ -1189,6 +1245,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 检查动画管理器当前状态 var animationState = _pathAnimationManager?.CurrentState ?? NavisworksTransport.Core.Animation.AnimationState.Stopped; var isAnimating = _pathAnimationManager?.IsAnimating ?? false; + + // 检查动画是否已经生成(Ready状态表示动画已生成但未播放) + var isAnimationReady = animationState == NavisworksTransport.Core.Animation.AnimationState.Ready || + animationState == NavisworksTransport.Core.Animation.AnimationState.Finished; // 根据动画状态和条件更新按钮状态 switch (animationState) @@ -1198,21 +1258,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels CanStartAnimation = false; CanPauseAnimation = true; CanStopAnimation = true; - AnimationStatus = "动画状态: 播放中"; + UpdateMainStatus("动画播放中"); break; case NavisworksTransport.Core.Animation.AnimationState.Paused: // 暂停中:开始按钮可用(显示为继续),暂停按钮禁用,停止按钮可用 - CanStartAnimation = hasValidAnimation; + CanStartAnimation = hasValidAnimation && isAnimationReady; CanPauseAnimation = false; CanStopAnimation = true; StartAnimationButtonText = "继续播放"; - AnimationStatus = "动画状态: 已暂停"; + UpdateMainStatus("动画已暂停"); break; default: - // 停止或其他状态:根据是否有有效动画来决定开始按钮状态 - CanStartAnimation = hasValidAnimation; + // 停止或其他状态:需要同时满足有效动画条件和动画已生成条件 + CanStartAnimation = hasValidAnimation && isAnimationReady; CanPauseAnimation = false; CanStopAnimation = false; StartAnimationButtonText = "开始动画"; @@ -1220,24 +1280,28 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 更新状态文本 if (!hasValidPath && !hasValidAnimatedObject) { - AnimationStatus = "动画状态: 请选择路径和移动物体"; + UpdateMainStatus("请选择路径和移动物体"); } else if (!hasValidPath) { - AnimationStatus = "动画状态: 请选择有效路径(至少2个点)"; + UpdateMainStatus("请选择有效路径(至少2个点)"); } else if (!hasValidAnimatedObject) { - AnimationStatus = "动画状态: 请选择移动物体"; + UpdateMainStatus("请选择移动物体"); + } + else if (!isAnimationReady) + { + UpdateMainStatus("请点击'生成动画'"); } else { - AnimationStatus = "动画状态: 就绪"; + UpdateMainStatus("动画就绪"); } break; } - LogManager.Debug($"按钮状态已更新: CanStart={CanStartAnimation}, CanPause={CanPauseAnimation}, CanStop={CanStopAnimation}, Status={AnimationStatus}"); + LogManager.Debug($"按钮状态已更新: CanStart={CanStartAnimation}, CanPause={CanPauseAnimation}, CanStop={CanStopAnimation}"); } catch (Exception ex) { @@ -1325,14 +1389,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels { // 通过检查是否有任何动画相关的碰撞测试来判断是否有结果 HasCollisionResults = true; // 假设动画完成后总是有结果可查看 - CollisionStatus = "动画完成,碰撞检测已完成"; - CollisionSummary = "请点击'查看碰撞报告'查看详细结果"; + UpdateMainStatus("动画完成,碰撞检测已完成"); LogManager.Info("动画完成后碰撞状态已更新"); } else { - CollisionStatus = "碰撞检测未就绪"; - CollisionSummary = "碰撞检测功能不可用"; + UpdateMainStatus("碰撞检测未就绪"); LogManager.Warning("ClashDetectiveIntegration实例不可用"); } })); @@ -1458,11 +1520,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels { // 🔧 修复:显示动画过程缓存的碰撞数量,而非测试数量 var animationCollisionCount = _clashIntegration?.AnimationCollisionCount ?? 0; - CollisionSummary = $"动画碰撞: {animationCollisionCount}个 | Clash Detective权威结果: {reportData.TotalCollisions}个"; + var summary = $"动画碰撞: {animationCollisionCount}个 | Clash Detective权威结果: {reportData.TotalCollisions}个"; + UpdateMainStatus("碰撞报告已生成"); } else { - CollisionSummary = $"报告生成失败:{reportData.ErrorMessage}"; + UpdateMainStatus($"报告生成失败:{reportData.ErrorMessage}"); } }); @@ -1566,6 +1629,67 @@ namespace NavisworksTransport.UI.WPF.ViewModels #endregion + #region 统一状态栏方法 + + /// + /// 更新统一状态栏(简单版本,不显示进度条) + /// + private void UpdateMainStatus(string message) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + + /// + /// 更新统一状态栏(支持百分比进度) + /// + private void UpdateMainStatus(string message, double percentage) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message, percentage); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + + /// + /// 更新统一状态栏(完整版本,支持不确定进度) + /// + private void UpdateMainStatus(string message, double progress = -1, bool? isProcessing = null) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message, progress, isProcessing); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + + #endregion + #region 资源清理 private bool _disposed = false; diff --git a/src/UI/WPF/ViewModels/PathEditingViewModel.cs b/src/UI/WPF/ViewModels/PathEditingViewModel.cs index e955893..0c42035 100644 --- a/src/UI/WPF/ViewModels/PathEditingViewModel.cs +++ b/src/UI/WPF/ViewModels/PathEditingViewModel.cs @@ -30,6 +30,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels private PathPlanningManager _pathPlanningManager; private readonly UIStateManager _uiStateManager; private readonly PathDataManager _pathDataManager; + private readonly LogisticsControlViewModel _mainViewModel; // 路径集合 private ObservableCollection _pathRoutes; @@ -40,8 +41,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 自动路径规划参数 private string _autoPathStartPoint = "未选择"; private string _autoPathEndPoint = "未选择"; - private string _autoPathStatus = "就绪"; - private string _pathEditTipText = "提示:点击[添加路径点]后,在3D视图中点击可通行的物流模型来添加路径点"; private Point3D _startPoint3D; private Point3D _endPoint3D; private bool _hasStartPoint = false; @@ -63,8 +62,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels private PathRoute _autoPathStartPointRoute = null; private PathRoute _autoPathEndPointRoute = null; - // 路径文件管理 - private string _pathFileStatus = "未保存"; // 资源清理管理 private bool _disposed = false; @@ -204,19 +201,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _autoPathEndPoint, value); } - public string AutoPathStatus - { - get => _autoPathStatus; - set => SetProperty(ref _autoPathStatus, value); - } - /// - /// 路径编辑提示文本 - /// - public string PathEditTipText - { - get => _pathEditTipText; - set => SetProperty(ref _pathEditTipText, value); - } public double VehicleLength { @@ -308,11 +292,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels #endregion - public string PathFileStatus - { - get => _pathFileStatus; - set => SetProperty(ref _pathFileStatus, value); - } public PathPlanningManager PathPlanningManager { @@ -419,7 +398,49 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"PathEditingViewModel构造函数异常: {ex.Message}", ex); - AutoPathStatus = "初始化失败,请检查日志"; + UpdateMainStatus("初始化失败,请检查日志"); + throw; + } + } + + /// + /// 带主ViewModel参数的构造函数,支持统一状态栏 + /// + /// 主ViewModel,用于统一状态栏 + public PathEditingViewModel(LogisticsControlViewModel mainViewModel) : base() + { + try + { + // 保存主ViewModel引用 + _mainViewModel = mainViewModel; + + _uiStateManager = UIStateManager.Instance; + _pathDataManager = new PathDataManager(); + // 不在构造函数中创建PathPlanningManager,由外部设置 + _pathPlanningManager = null; + + if (_uiStateManager == null) + { + throw new InvalidOperationException("UIStateManager初始化失败"); + } + + // PathPlanningManager将在外部设置,这里不需要检查 + + // 初始化集合 + PathRoutes = new ObservableCollection(); + + // 初始化命令 + InitializeCommands(); + + // 注意:不在这里订阅PathPlanningManager事件, + // 因为PathPlanningManager还没有设置,事件订阅在PathPlanningManager属性setter中处理 + + LogManager.Info("PathEditingViewModel构造函数执行完成 - 支持统一状态栏"); + } + catch (Exception ex) + { + LogManager.Error($"PathEditingViewModel构造函数异常: {ex.Message}", ex); + UpdateMainStatus("初始化失败,请检查日志"); throw; } } @@ -458,7 +479,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await SafeExecuteAsync(() => { - AutoPathStatus = "正在创建新路径..."; + UpdateMainStatus("正在创建新路径..."); // 清除所有现有路径的可视化显示 if (PathPointRenderPlugin.Instance != null) @@ -511,19 +532,19 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 强制重新初始化ToolPlugin以确保获得鼠标焦点,新建路径需要订阅事件 if (!ForceReinitializeToolPlugin(subscribeToEvents: true)) { - AutoPathStatus = "ToolPlugin初始化失败,请重试"; + UpdateMainStatus("ToolPlugin初始化失败,请重试"); LogManager.Error("新建路径:ToolPlugin初始化失败"); return; } - AutoPathStatus = $"已进入新建路径模式: {newRoute.Name} - 请在3D视图中点击设置路径点"; + UpdateMainStatus($"已进入新建路径模式: {newRoute.Name} - 请在3D视图中点击设置路径点"); LogManager.Info($"开始新建路径: {newRoute.Name},已强制重新初始化ToolPlugin获取鼠标焦点"); // 不再显示对话框,状态文本已提供足够的反馈 } else { - AutoPathStatus = "创建新路径失败:没有可通行的物流模型"; + UpdateMainStatus("创建新路径失败:没有可通行的物流模型"); LogManager.Error("创建新路径失败:没有可通行的物流模型"); MessageBox.Show("创建新路径失败:没有找到任何可通行的物流模型。\n请先为模型设置可通行的物流属性,然后再尝试创建路径。", "错误", MessageBoxButton.OK, MessageBoxImage.Warning); @@ -531,7 +552,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels } else { - AutoPathStatus = "路径规划管理器未初始化"; + UpdateMainStatus("路径规划管理器未初始化"); LogManager.Error("路径规划管理器未初始化"); } }, "新建路径"); @@ -544,7 +565,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels await SafeExecuteAsync(() => { var pathName = SelectedPathRoute.Name; - AutoPathStatus = $"正在删除路径: {pathName}..."; + UpdateMainStatus($"正在删除路径: {pathName}..."); // 清理当前路径的3D可视化显示(使用新的统一API) if (PathPointRenderPlugin.Instance != null) @@ -591,7 +612,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 更新UI PathRoutes.Remove(SelectedPathRoute); SelectedPathRoute = null; - AutoPathStatus = $"已完全删除路径: {pathName}"; + UpdateMainStatus($"已完全删除路径: {pathName}"); }, "删除路径"); } @@ -608,7 +629,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (_pathPlanningManager == null) { LogManager.Error("PathPlanningManager为null,无法选择起点"); - AutoPathStatus = "路径规划管理器未初始化"; + UpdateMainStatus("路径规划管理器未初始化"); return; } @@ -627,7 +648,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Info("PathPlanningManager已初始化,开始设置选择状态"); IsSelectingStartPoint = true; IsSelectingEndPoint = false; - AutoPathStatus = "请在3D视图中点击选择起点..."; + UpdateMainStatus("请在3D视图中点击选择起点..."); // 进入自动路径规划模式 - 动态事件订阅 LogManager.Info("进入自动路径规划模式,启用动态事件订阅"); @@ -643,7 +664,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 强制重新初始化ToolPlugin以确保获得鼠标焦点,自动路径不需要PathPlanningManager订阅事件 if (!ForceReinitializeToolPlugin(subscribeToEvents: false)) { - AutoPathStatus = "ToolPlugin初始化失败,请重试"; + UpdateMainStatus("ToolPlugin初始化失败,请重试"); return; } @@ -662,7 +683,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (_pathPlanningManager == null) { LogManager.Error("PathPlanningManager为null,无法选择终点"); - AutoPathStatus = "路径规划管理器未初始化"; + UpdateMainStatus("路径规划管理器未初始化"); return; } @@ -681,7 +702,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Info("PathPlanningManager已初始化,开始设置选择状态"); IsSelectingStartPoint = false; IsSelectingEndPoint = true; - AutoPathStatus = "请在3D视图中点击选择终点..."; + UpdateMainStatus("请在3D视图中点击选择终点..."); // 进入自动路径规划模式 - 动态事件订阅 LogManager.Info("进入自动路径规划模式,启用动态事件订阅"); @@ -697,7 +718,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 强制重新初始化ToolPlugin以确保获得鼠标焦点,自动路径不需要PathPlanningManager订阅事件 if (!ForceReinitializeToolPlugin(subscribeToEvents: false)) { - AutoPathStatus = "ToolPlugin初始化失败,请重试"; + UpdateMainStatus("ToolPlugin初始化失败,请重试"); return; } @@ -713,11 +734,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels { if (!_hasStartPoint || !_hasEndPoint) { - AutoPathStatus = "请先选择起点和终点"; + UpdateMainStatus("请先选择起点和终点"); return; } - AutoPathStatus = "正在计算最优路径..."; + UpdateMainStatus("正在计算最优路径...", -1, true); LogManager.Info("=== 开始执行自动路径规划 ==="); // 确保在开始自动路径规划前清理任何残留的事件订阅 @@ -786,23 +807,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 不在这里直接操作UI,让RouteGenerated事件处理UI更新 // 这避免了重复的路径添加和UI更新冲突 - // 不在这里设置AutoPathStatus,让RouteGenerated事件处理UI更新 + // 不在这里设置状态,让RouteGenerated事件处理UI更新 LogManager.Info($"✅ 自动路径规划完成,RouteGenerated事件将处理UI更新"); } else { - // 检查是否已经通过ErrorOccurred事件设置了详细错误信息 - if (!AutoPathStatus.Contains("❌ 自动路径规划失败")) - { - // 如果没有详细错误信息,则设置通用错误提示 - AutoPathStatus = "❌ 路径规划失败,未找到可行路径"; - LogManager.Warning("自动路径规划失败:未找到可行路径"); - } - else - { - // 如果已有详细错误信息,保留不覆盖 - LogManager.Info("保留ErrorOccurred事件设置的详细错误信息,不覆盖AutoPathStatus"); - } + // 这里的逻辑已经在上方处理过了 // 失败情况下也要清理事件订阅和临时标记 LogManager.WriteLog("[自动路径规划] 规划失败后清理所有状态"); @@ -868,7 +878,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels _endPoint3D = new Point3D(); AutoPathStartPoint = "未选择"; AutoPathEndPoint = "未选择"; - AutoPathStatus = "就绪"; + UpdateMainStatus("就绪"); IsSelectingStartPoint = false; IsSelectingEndPoint = false; @@ -899,8 +909,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels var newName = $"路径 {PathRoutes.Count}"; var oldName = SelectedPathRoute.Name; SelectedPathRoute.Name = newName; - AutoPathStatus = $"路径已重命名: {oldName} -> {newName}"; - PathFileStatus = "未保存"; + UpdateMainStatus($"路径已重命名: {oldName} -> {newName}"); }); }, "重命名路径"); } @@ -917,7 +926,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (SelectedPathRoute != null) { SelectedPathRoute.IsActive = true; - AutoPathStatus = $"正在激活3D路径编辑模式: {SelectedPathRoute.Name}..."; + UpdateMainStatus($"正在激活3D路径编辑模式: {SelectedPathRoute.Name}..."); // 启动PathPlanningManager的点击工具,这会设置正确的编辑状态 if (_pathPlanningManager != null) @@ -930,21 +939,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"启动点击工具失败: {ex.Message}"); - AutoPathStatus = "启动3D编辑工具失败,请重试"; + UpdateMainStatus("启动3D编辑工具失败,请重试"); IsPathEditMode = false; return; } } else { - AutoPathStatus = "路径规划管理器未初始化"; + UpdateMainStatus("路径规划管理器未初始化"); LogManager.Error("添加路径点:PathPlanningManager未初始化"); IsPathEditMode = false; return; } - AutoPathStatus = $"已进入3D路径编辑模式: {SelectedPathRoute.Name}"; - PathEditTipText = "✓ 预览模式已激活 - 在3D视图中点击设置灰色预览点,满意后点击[确认]添加到路径,继续编辑或点击[结束]完成"; + UpdateMainStatus($"已进入3D路径编辑模式: {SelectedPathRoute.Name} - 在3D视图中点击设置路径点"); LogManager.Info($"开始添加路径点: {SelectedPathRoute.Name},已启动点击工具"); // 手动触发按钮状态更新 @@ -1023,18 +1031,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels { if (_pathPlanningManager?.PathEditState == PathEditState.EditingPoint || operationMessage.Contains("路径点修改")) { - AutoPathStatus = $"✅ 路径点修改完成: {SelectedPathRoute.Name}"; - PathEditTipText = "路径点修改已完成"; + UpdateMainStatus($"✅ 路径点修改完成: {SelectedPathRoute.Name}"); } else if (wasInPreviewMode) { - AutoPathStatus = $"✅ 预览点已确认,路径编辑完成: {SelectedPathRoute.Name}"; + UpdateMainStatus($"✅ 预览点已确认,路径编辑完成: {SelectedPathRoute.Name}"); } else { - AutoPathStatus = $"✅ 路径编辑完成: {SelectedPathRoute.Name} - 最后一个点已自动设置为终点"; + UpdateMainStatus($"✅ 路径编辑完成: {SelectedPathRoute.Name} - 最后一个点已自动设置为终点"); } - PathFileStatus = "已完成"; } LogManager.Info("[UI状态] 路径编辑完成,等待状态变更事件更新按钮"); @@ -1044,8 +1050,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 编辑完成失败 if (SelectedPathRoute != null) { - AutoPathStatus = $"❌ 路径编辑失败: {SelectedPathRoute.Name}"; - PathFileStatus = "编辑失败"; + UpdateMainStatus($"❌ 路径编辑失败: {SelectedPathRoute.Name}"); } LogManager.Error("[UI状态] 路径编辑失败"); @@ -1070,8 +1075,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels await _uiStateManager.ExecuteUIUpdateAsync(() => { SelectedPathRoute.Points.Clear(); - AutoPathStatus = $"已清空路径 {SelectedPathRoute.Name} 的 {pointCount} 个点"; - PathFileStatus = "未保存"; + UpdateMainStatus($"已清空路径 {SelectedPathRoute.Name} 的 {pointCount} 个点"); }); }, "清空路径"); } @@ -1120,8 +1124,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels } // 4. 更新UI状态 - AutoPathStatus = $"已删除路径点: {point.Name}"; - PathFileStatus = "未保存"; + UpdateMainStatus($"已删除路径点: {point.Name}"); LogManager.Info($"路径点删除完成,当前UI点数: {SelectedPathRoute.Points.Count}, Core点数: {coreRoute?.Points.Count ?? 0}"); }); @@ -1174,14 +1177,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (success) { - AutoPathStatus = $"正在修改路径点: {SelectedPathPoint.Name} - 请在3D视图中点击新位置"; - PathEditTipText = "修改路径点模式:在3D视图中点击选择新位置,然后点击'确认'按钮完成修改"; + UpdateMainStatus($"正在修改路径点: {SelectedPathPoint.Name} - 请在3D视图中点击新位置"); LogManager.Info($"已开始修改路径点: {SelectedPathPoint.Name}, 索引: {pointIndex}"); - // 更新UI状态 - OnPropertyChanged(nameof(AutoPathStatus)); - OnPropertyChanged(nameof(PathEditTipText)); - // 刷新命令状态 OnPropertyChanged(nameof(CanExecuteStartEdit)); OnPropertyChanged(nameof(CanExecuteEndEdit)); @@ -1190,13 +1188,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels } else { - AutoPathStatus = "修改路径点失败,请检查路径状态"; + UpdateMainStatus("修改路径点失败,请检查路径状态"); LogManager.Error($"开始修改路径点失败: {SelectedPathPoint.Name}, 索引: {pointIndex}"); } } else { - AutoPathStatus = "找不到选中的路径点"; + UpdateMainStatus("找不到选中的路径点"); LogManager.Error($"找不到路径点索引 - 选中点Id: {SelectedPathPoint.Id}, 选中点名称: {SelectedPathPoint.Name}"); LogManager.Error("可能原因:1)选中的路径点与当前路径不匹配 2)路径点数据不同步 3)Id不匹配"); } @@ -1205,12 +1203,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels { if (currentRoute == null) { - AutoPathStatus = "当前没有活动路径"; + UpdateMainStatus("当前没有活动路径"); LogManager.Error("尝试修改路径点时没有当前路径"); } else { - AutoPathStatus = "当前路径没有路径点数据"; + UpdateMainStatus("当前路径没有路径点数据"); LogManager.Error("当前路径的Points集合为空"); } } @@ -1219,12 +1217,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels { if (SelectedPathPoint == null) { - AutoPathStatus = "请先选中要修改的路径点"; + UpdateMainStatus("请先选中要修改的路径点"); LogManager.Warning("修改路径点时没有选中路径点"); } else { - AutoPathStatus = "路径规划管理器未初始化"; + UpdateMainStatus("路径规划管理器未初始化"); LogManager.Error("修改路径点时PathPlanningManager为空"); } } @@ -1250,20 +1248,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (success) { - AutoPathStatus = "已取消修改路径点"; - PathEditTipText = "修改路径点操作已取消"; + UpdateMainStatus("已取消修改路径点"); LogManager.Info("用户取消了修改路径点操作"); } else { - AutoPathStatus = "取消修改路径点失败"; + UpdateMainStatus("取消修改路径点失败"); LogManager.Error("取消修改路径点失败"); } - // 更新UI状态 - OnPropertyChanged(nameof(AutoPathStatus)); - OnPropertyChanged(nameof(PathEditTipText)); - // 刷新命令状态 OnPropertyChanged(nameof(CanExecuteStartEdit)); OnPropertyChanged(nameof(CanExecuteEndEdit)); @@ -1350,11 +1343,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels var importResult = (result as PathPlanningResult)?.Data; if (importResult != null) { - AutoPathStatus = $"✅ 导入成功: {importResult.ImportedCount}/{importResult.TotalInFile} 个路径"; + var statusMessage = $"✅ 导入成功: {importResult.ImportedCount}/{importResult.TotalInFile} 个路径"; if (importResult.FailedCount > 0) { - AutoPathStatus += $" (失败 {importResult.FailedCount} 个)"; + statusMessage += $" (失败 {importResult.FailedCount} 个)"; } + UpdateMainStatus(statusMessage); if (!string.IsNullOrEmpty(importResult.BackupFilePath)) { LogManager.Info($"导入前备份已创建: {importResult.BackupFilePath}"); @@ -1362,15 +1356,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels } else { - AutoPathStatus = $"✅ 路径导入完成: {Path.GetFileName(filePath)}"; + UpdateMainStatus($"✅ 路径导入完成: {Path.GetFileName(filePath)}"); } - - PathFileStatus = "已导入"; } else { - AutoPathStatus = $"❌ 导入失败: {result.ErrorMessage}"; - PathFileStatus = "导入失败"; + UpdateMainStatus($"❌ 导入失败: {result.ErrorMessage}"); LogManager.Error($"路径导入失败: {result.ErrorMessage}"); } } @@ -1378,8 +1369,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"导入路径异常: {ex.Message}", ex); - AutoPathStatus = $"❌ 导入异常: {ex.Message}"; - PathFileStatus = "导入异常"; + UpdateMainStatus($"❌ 导入异常: {ex.Message}"); } }, "导入路径"); } @@ -1444,24 +1434,22 @@ namespace NavisworksTransport.UI.WPF.ViewModels var exportResult = (result as PathPlanningResult)?.Data; if (exportResult != null) { - AutoPathStatus = $"✅ 导出全部成功: {exportResult.ExportedCount} 个路径到 {Path.GetFileName(filePath)}"; + var statusMessage = $"✅ 导出全部成功: {exportResult.ExportedCount} 个路径到 {Path.GetFileName(filePath)}"; if (exportResult.FailedCount > 0) { - AutoPathStatus += $" (失败 {exportResult.FailedCount} 个)"; + statusMessage += $" (失败 {exportResult.FailedCount} 个)"; } + UpdateMainStatus(statusMessage); LogManager.Info($"导出完成,文件大小: {exportResult.FileSizeMB:F2} MB"); } else { - AutoPathStatus = $"✅ 全部路径导出完成: {Path.GetFileName(filePath)}"; + UpdateMainStatus($"✅ 全部路径导出完成: {Path.GetFileName(filePath)}"); } - - PathFileStatus = "已导出"; } else { - AutoPathStatus = $"❌ 导出全部失败: {result.ErrorMessage}"; - PathFileStatus = "导出全部失败"; + UpdateMainStatus($"❌ 导出全部失败: {result.ErrorMessage}"); LogManager.Error($"全部路径导出失败: {result.ErrorMessage}"); } } @@ -1469,8 +1457,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"导出全部路径异常: {ex.Message}", ex); - AutoPathStatus = $"❌ 导出全部异常: {ex.Message}"; - PathFileStatus = "导出全部异常"; + UpdateMainStatus($"❌ 导出全部异常: {ex.Message}"); } }, "导出全部路径"); } @@ -1539,35 +1526,30 @@ namespace NavisworksTransport.UI.WPF.ViewModels var exportResult = (result as PathPlanningResult)?.Data; if (exportResult != null) { - AutoPathStatus = $"✅ 导出选中路径成功: {SelectedPathRoute.Name} -> {Path.GetFileName(filePath)}"; + UpdateMainStatus($"✅ 导出选中路径成功: {SelectedPathRoute.Name} -> {Path.GetFileName(filePath)}"); LogManager.Info($"导出选中路径完成,文件大小: {exportResult.FileSizeMB:F2} MB"); } else { - AutoPathStatus = $"✅ 导出选中路径完成: {Path.GetFileName(filePath)}"; + UpdateMainStatus($"✅ 导出选中路径完成: {Path.GetFileName(filePath)}"); } - - PathFileStatus = "已导出选中路径"; } else { - AutoPathStatus = $"❌ 导出选中路径失败: {result.ErrorMessage}"; - PathFileStatus = "导出选中路径失败"; + UpdateMainStatus($"❌ 导出选中路径失败: {result.ErrorMessage}"); LogManager.Error($"导出选中路径失败: {result.ErrorMessage}"); } } else { - AutoPathStatus = $"❌ 导出选中路径失败:找不到对应的Core路径: {SelectedPathRoute.Name}"; - PathFileStatus = "导出选中路径失败"; + UpdateMainStatus($"❌ 导出选中路径失败:找不到对应的Core路径: {SelectedPathRoute.Name}"); } } } catch (Exception ex) { LogManager.Error($"导出选中路径异常: {ex.Message}", ex); - AutoPathStatus = $"❌ 导出选中路径异常: {ex.Message}"; - PathFileStatus = "导出选中路径异常"; + UpdateMainStatus($"❌ 导出选中路径异常: {ex.Message}"); } }, "导出选中路径"); } @@ -1690,7 +1672,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"[自动路径事件] 处理点击事件异常: {ex.Message}"); - AutoPathStatus = $"获取点击位置失败: {ex.Message}"; + UpdateMainStatus($"获取点击位置失败: {ex.Message}"); IsSelectingStartPoint = false; IsSelectingEndPoint = false; @@ -1748,11 +1730,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (_hasEndPoint) { - AutoPathStatus = "起点和终点已设置,可以开始路径规划"; + UpdateMainStatus("起点和终点已设置,可以开始路径规划"); } else { - AutoPathStatus = "起点已设置,请选择终点"; + UpdateMainStatus("起点已设置,请选择终点"); } LogManager.Info($"起点已设置: ({point.X:F2}, {point.Y:F2}, {point.Z:F2})"); @@ -1798,11 +1780,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (_hasStartPoint) { - AutoPathStatus = "起点和终点已设置,可以开始路径规划"; + UpdateMainStatus("起点和终点已设置,可以开始路径规划"); } else { - AutoPathStatus = "终点已设置,请选择起点"; + UpdateMainStatus("终点已设置,请选择起点"); } LogManager.Info($"终点已设置: ({point.X:F2}, {point.Y:F2}, {point.Z:F2})"); @@ -1825,7 +1807,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"{operationName}发生异常: {ex.Message}", ex); - AutoPathStatus = $"{operationName}失败: {ex.Message}"; + UpdateMainStatus($"{operationName}失败: {ex.Message}"); } } @@ -2030,12 +2012,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels SelectedPathRoute = pathViewModel; } - AutoPathStatus = $"已添加路径点: {e.PathPoint.Name} 到 {e.Route.Name}"; + UpdateMainStatus($"已添加路径点: {e.PathPoint.Name} 到 {e.Route.Name}"); LogManager.Info($"路径点操作完成: {e.PathPoint.Name} 已添加到路径 {e.Route.Name}"); } else if (e.OperationType == PathPointOperationType.Removed) { - AutoPathStatus = $"已移除路径点: {e.PathPoint.Name} 从 {e.Route.Name}"; + UpdateMainStatus($"已移除路径点: {e.PathPoint.Name} 从 {e.Route.Name}"); LogManager.Info($"路径点操作完成: {e.PathPoint.Name} 已从路径 {e.Route.Name} 移除"); } }, "处理路径点操作事件"); @@ -2211,27 +2193,28 @@ namespace NavisworksTransport.UI.WPF.ViewModels switch (e.NewState) { case PathEditState.Creating: - AutoPathStatus = $"正在新建路径: {e.EditingRoute?.Name} - 请在3D视图中点击设置路径点"; + UpdateMainStatus($"正在新建路径: {e.EditingRoute?.Name} - 请在3D视图中点击设置路径点"); break; case PathEditState.Editing: - AutoPathStatus = $"正在编辑路径: {e.EditingRoute?.Name} - 请在3D视图中点击设置路径点"; + UpdateMainStatus($"正在编辑路径: {e.EditingRoute?.Name} - 请在3D视图中点击设置路径点"); break; case PathEditState.AddingPoints: - AutoPathStatus = $"正在添加路径点到: {e.EditingRoute?.Name} - 请在3D视图中点击设置路径点"; + UpdateMainStatus($"正在添加路径点到: {e.EditingRoute?.Name} - 请在3D视图中点击设置路径点"); break; case PathEditState.EditingPoint: - AutoPathStatus = $"正在修改路径点: {e.EditingRoute?.Name} - 请在3D视图中点击新位置,然后点击'结束'确认"; + UpdateMainStatus($"正在修改路径点: {e.EditingRoute?.Name} - 请在3D视图中点击新位置,然后点击'结束'确认"); break; case PathEditState.Viewing: // 如果当前状态包含路径规划完成信息(包括完成度百分比),则保留不覆盖 - if (!AutoPathStatus.Contains("路径规划完成") && !AutoPathStatus.Contains("路径规划部分完成") && - !AutoPathStatus.Contains("✅") && !AutoPathStatus.Contains("🔶")) + var currentStatus = _mainViewModel?.StatusText ?? ""; + if (!currentStatus.Contains("路径规划完成") && !currentStatus.Contains("路径规划部分完成") && + !currentStatus.Contains("✅") && !currentStatus.Contains("🔶")) { - AutoPathStatus = "路径编辑已完成"; + UpdateMainStatus("路径编辑已完成"); } break; default: - AutoPathStatus = "就绪"; + UpdateMainStatus("就绪"); break; } @@ -2338,8 +2321,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels statusMessage = $"🔶 自动路径规划部分完成: {e.Route.Name},共 {e.Route.Points.Count} 个路径点,长度 {e.Route.TotalLength:F2}米,(完成度: {e.Route.CompletionPercentage:F1}%)"; } - AutoPathStatus = statusMessage; - LogManager.Info($"*** AutoPathStatus已更新: {AutoPathStatus} ***"); + UpdateMainStatus(statusMessage); + LogManager.Info($"*** 状态已更新: {statusMessage} ***"); } else if (e.GenerationMethod == RouteGenerationMethod.Manual) { @@ -2377,8 +2360,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels await _uiStateManager.ExecuteUIUpdateAsync(() => { // 更新自动路径状态显示错误信息 - AutoPathStatus = $"❌ 自动路径规划失败: {e.ErrorMessage}"; - LogManager.Info($"*** AutoPathStatus已更新为: {AutoPathStatus} ***"); + UpdateMainStatus($"❌ 自动路径规划失败: {e.ErrorMessage}"); + LogManager.Info($"*** 状态已更新为: ❌ 自动路径规划失败: {e.ErrorMessage} ***"); }); }, "处理路径规划错误事件"); @@ -2391,6 +2374,67 @@ namespace NavisworksTransport.UI.WPF.ViewModels #endregion + #region 统一状态栏方法 + + /// + /// 更新统一状态栏(简单版本,不显示进度条) + /// + private void UpdateMainStatus(string message) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + + /// + /// 更新统一状态栏(支持百分比进度) + /// + private void UpdateMainStatus(string message, double percentage) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message, percentage); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + + /// + /// 更新统一状态栏(完整版本,支持不确定进度) + /// + private void UpdateMainStatus(string message, double progress = -1, bool? isProcessing = null) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message, progress, isProcessing); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + + #endregion + #region 清理资源 /// diff --git a/src/UI/WPF/ViewModels/SystemManagementViewModel.cs b/src/UI/WPF/ViewModels/SystemManagementViewModel.cs index 4da6258..1f1c2aa 100644 --- a/src/UI/WPF/ViewModels/SystemManagementViewModel.cs +++ b/src/UI/WPF/ViewModels/SystemManagementViewModel.cs @@ -18,6 +18,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels #region 私有字段 private readonly UIStateManager _uiStateManager; + private readonly LogisticsControlViewModel _mainViewModel; // 系统管理相关字段 private bool _isAutoSaveEnabled = true; @@ -29,15 +30,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels private bool _showUnknownGrid = false; private ObservableCollection _logLevels; private string _selectedLogLevel = "Info"; - private string _logStatus = "日志系统正常"; private string _pluginVersion = "v1.0"; private string _navisworksVersion = "2026"; - private string _settingsStatus = "设置已加载"; - private string _systemStatus = "正常"; - private string _systemStatusColor = "Green"; private string _memoryUsage = "0 MB"; private string _runningTime = "00:00:00"; - private string _performanceInfo = "性能监控就绪"; // 🔧 修复:添加定时器字段以便在清理时停止 private System.Windows.Threading.DispatcherTimer _performanceTimer; @@ -130,14 +126,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _selectedLogLevel, value); } - /// - /// 日志状态 - /// - public string LogStatus - { - get => _logStatus; - set => SetProperty(ref _logStatus, value); - } /// @@ -158,32 +146,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _navisworksVersion, value); } - /// - /// 设置状态 - /// - public string SettingsStatus - { - get => _settingsStatus; - set => SetProperty(ref _settingsStatus, value); - } - /// - /// 系统状态 - /// - public string SystemStatus - { - get => _systemStatus; - set => SetProperty(ref _systemStatus, value); - } - /// - /// 系统状态颜色 - /// - public string SystemStatusColor - { - get => _systemStatusColor; - set => SetProperty(ref _systemStatusColor, value); - } /// /// 内存使用情况 @@ -203,14 +167,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _runningTime, value); } - /// - /// 性能信息 - /// - public string PerformanceInfo - { - get => _performanceInfo; - set => SetProperty(ref _performanceInfo, value); - } #endregion @@ -260,7 +216,49 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Error($"SystemManagementViewModel构造函数异常: {ex.Message}", ex); // 在构造函数中尽量保证对象处于可用状态 - SystemStatus = "初始化失败,请检查日志"; + UpdateMainStatus("初始化失败,请检查日志"); + throw; + } + } + + /// + /// 带主ViewModel参数的构造函数,支持统一状态栏 + /// + /// 主ViewModel,用于统一状态栏 + public SystemManagementViewModel(LogisticsControlViewModel mainViewModel) : base() + { + try + { + // 保存主ViewModel引用 + _mainViewModel = mainViewModel; + + // 获取UI状态管理器实例 + _uiStateManager = UIStateManager.Instance; + + // 验证关键组件是否正常初始化 + if (_uiStateManager == null) + { + LogManager.Error("UIStateManager初始化失败"); + throw new InvalidOperationException("UIStateManager初始化失败"); + } + + // 初始化线程安全的集合 + LogLevels = new ThreadSafeObservableCollection(); + + // 初始化命令 + InitializeCommands(); + + // 初始化系统管理设置 + InitializeSystemManagementSettingsAsync(); + + LogManager.Info("SystemManagementViewModel构造函数执行完成 - 支持统一状态栏"); + } + catch (Exception ex) + { + LogManager.Error($"SystemManagementViewModel构造函数异常: {ex.Message}", ex); + + // 在构造函数中尽量保证对象处于可用状态 + UpdateMainStatus("初始化失败,请检查日志"); throw; } } @@ -315,18 +313,18 @@ namespace NavisworksTransport.UI.WPF.ViewModels showObstacle: ShowObstacleGrid, showUnknown: ShowUnknownGrid); - SettingsStatus = "网格可视化设置已更新"; + UpdateMainStatus("网格可视化设置已更新"); } else { LogManager.Warning("无法获取路径规划管理器,网格可视化设置可能不会立即生效"); - SettingsStatus = "网格可视化设置已保存"; + UpdateMainStatus("网格可视化设置已保存"); } } catch (Exception ex) { LogManager.Error($"应用网格可视化设置失败: {ex.Message}", ex); - SettingsStatus = "网格可视化设置应用失败"; + UpdateMainStatus("网格可视化设置应用失败"); } } @@ -377,12 +375,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels SelectedLogLevel = "Info"; // 初始化系统信息 - LogStatus = "日志系统正常"; - SettingsStatus = "设置已加载"; PluginVersion = "v1.0"; NavisworksVersion = "2026"; - SystemStatus = "正常"; - SystemStatusColor = "Green"; + UpdateMainStatus("系统管理初始化完成"); }); // 启动性能监控 @@ -430,8 +425,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels var runTime = DateTime.Now - startTime; RunningTime = $"{runTime.Hours:D2}:{runTime.Minutes:D2}:{runTime.Seconds:D2}"; - // 更新性能信息 - PerformanceInfo = $"CPU: 正常, 内存: {memoryMB}MB, 运行时间: {RunningTime}"; + // 性能信息更新已合并到统一状态栏 } catch (Exception ex) { @@ -497,12 +491,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 显示对话框(使用Show而不是ShowDialog以避免阻塞) logViewerDialog.Show(); - LogStatus = "日志查看器已打开"; + UpdateMainStatus("日志查看器已打开"); LogManager.Info("通过系统管理打开日志查看器"); } catch (Exception ex) { - LogStatus = "打开日志查看器失败"; + UpdateMainStatus("打开日志查看器失败"); LogManager.Error($"打开日志查看器失败: {ex.Message}", ex); // 显示错误消息给用户 @@ -534,7 +528,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 调用LogManager清空日志 LogManager.ClearLog(); - LogStatus = "日志已清空"; + UpdateMainStatus("日志已清空"); LogManager.Info("通过系统管理清空日志"); // 显示成功消息 @@ -544,13 +538,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels } else { - LogStatus = "取消清空日志"; + UpdateMainStatus("取消清空日志"); LogManager.Info("用户取消清空日志操作"); } } catch (Exception ex) { - LogStatus = "清空日志失败"; + UpdateMainStatus("清空日志失败"); LogManager.Error($"清空日志失败: {ex.Message}", ex); // 显示错误消息给用户 @@ -588,7 +582,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 从源日志文件复制到目标位置 System.IO.File.Copy(logFilePath, saveFileDialog.FileName, true); - LogStatus = $"日志已导出到: {System.IO.Path.GetFileName(saveFileDialog.FileName)}"; + UpdateMainStatus($"日志已导出到: {System.IO.Path.GetFileName(saveFileDialog.FileName)}"); LogManager.Info($"日志已导出到: {saveFileDialog.FileName}"); // 显示成功消息并询问是否打开文件夹 @@ -609,7 +603,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 如果日志文件不存在,创建一个空的日志文件 System.IO.File.WriteAllText(saveFileDialog.FileName, $"NavisworksTransport 日志文件\n导出时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}\n\n日志文件为空或不存在。\n"); - LogStatus = "日志文件不存在,已创建空文件"; + UpdateMainStatus("日志文件不存在,已创建空文件"); LogManager.Warning("日志文件不存在,已创建空的导出文件"); System.Windows.MessageBox.Show("原始日志文件不存在,已创建空的导出文件。", "注意", @@ -619,13 +613,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels } else { - LogStatus = "取消导出日志"; + UpdateMainStatus("取消导出日志"); LogManager.Info("用户取消导出日志操作"); } } catch (Exception ex) { - LogStatus = "导出日志失败"; + UpdateMainStatus("导出日志失败"); LogManager.Error($"导出日志失败: {ex.Message}", ex); // 显示错误消息给用户 @@ -644,7 +638,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels SafeExecute(() => { // TODO: 实现设置对话框 - SettingsStatus = "打开插件设置"; + UpdateMainStatus("打开插件设置"); LogManager.Info("打开设置"); }, "打开设置"); } @@ -657,7 +651,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels SafeExecute(() => { // TODO: 实现设置重置功能 - SettingsStatus = "设置已重置为默认值"; + UpdateMainStatus("设置已重置为默认值"); IsAutoSaveEnabled = true; IsDebugModeEnabled = false; LogManager.Info("重置设置"); @@ -672,7 +666,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels SafeExecute(() => { // TODO: 实现配置导入功能 - SettingsStatus = "配置导入完成"; + UpdateMainStatus("配置导入完成"); LogManager.Info("导入配置"); }, "导入配置"); } @@ -684,7 +678,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { SafeExecute(() => { - SystemStatus = "正在检查更新..."; + UpdateMainStatus("正在检查更新..."); // 模拟检查更新 System.Threading.Tasks.Task.Run(() => @@ -702,7 +696,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels return; } - SystemStatus = "当前版本已是最新版本"; + UpdateMainStatus("当前版本已是最新版本"); } catch (Exception ex) { @@ -722,7 +716,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { SafeExecute(() => { - SystemStatus = "正在生成性能报告..."; + UpdateMainStatus("正在生成性能报告..."); // 模拟生成报告 System.Threading.Tasks.Task.Run(() => @@ -740,8 +734,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels return; } - SystemStatus = "性能报告生成完成"; - PerformanceInfo = $"报告已生成 - {DateTime.Now:yyyy-MM-dd HH:mm:ss}"; + UpdateMainStatus("性能报告生成完成"); + // 性能信息更新已合并到统一状态栏 } catch (Exception ex) { @@ -841,7 +835,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 5. 系统信息 report.AppendLine($"插件版本: {PluginVersion}"); report.AppendLine($"Navisworks版本: {NavisworksVersion}"); - report.AppendLine($"系统状态: {SystemStatus}"); + report.AppendLine("系统状态: 正常"); report.AppendLine("=== 诊断完成 ==="); @@ -862,6 +856,63 @@ namespace NavisworksTransport.UI.WPF.ViewModels #region 辅助方法 + /// + /// 更新统一状态栏(简单版本,不显示进度条) + /// + private void UpdateMainStatus(string message) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + + /// + /// 更新统一状态栏(支持百分比进度) + /// + private void UpdateMainStatus(string message, double percentage) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message, percentage); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + + /// + /// 更新统一状态栏(完整版本,支持不确定进度) + /// + private void UpdateMainStatus(string message, double progress = -1, bool? isProcessing = null) + { + try + { + // 如果有主ViewModel引用,更新统一状态栏 + if (_mainViewModel != null) + { + _mainViewModel.UpdateStatus(message, progress, isProcessing); + } + } + catch (Exception ex) + { + LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); + } + } + /// /// 安全执行异步操作 /// @@ -874,7 +925,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"{operationName}发生异常: {ex.Message}", ex); - SystemStatus = $"{operationName}失败: {ex.Message}"; + UpdateMainStatus($"{operationName}失败: {ex.Message}"); } } @@ -890,7 +941,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels catch (Exception ex) { LogManager.Error($"{operationName}发生异常: {ex.Message}", ex); - SystemStatus = $"{operationName}失败: {ex.Message}"; + UpdateMainStatus($"{operationName}失败: {ex.Message}"); } } @@ -909,8 +960,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels public string GetStateInfo() { return $"UIStateManager: {(_uiStateManager != null ? "已初始化" : "未初始化")}, " + - $"日志级别数量: {LogLevels?.Count ?? 0}, " + - $"系统状态: {SystemStatus}"; + $"日志级别数量: {LogLevels?.Count ?? 0}"; } #endregion diff --git a/src/UI/WPF/Views/AnimationControlView.xaml b/src/UI/WPF/Views/AnimationControlView.xaml index 7439243..71f29bf 100644 --- a/src/UI/WPF/Views/AnimationControlView.xaml +++ b/src/UI/WPF/Views/AnimationControlView.xaml @@ -243,11 +243,6 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管 Style="{StaticResource SecondaryButtonStyle}" Height="28" Padding="12,4"/> - @@ -280,11 +275,6 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管 Style="{StaticResource SecondaryButtonStyle}"/> - - @@ -331,16 +321,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管 Style="{StaticResource ActionButtonStyle}"/> - - - - + /// 带主ViewModel参数的构造函数,支持统一状态栏 + /// + /// 主ViewModel,用于统一状态栏 + public AnimationControlView(LogisticsControlViewModel mainViewModel) + { + InitializeComponent(); + InitializeViewModel(mainViewModel); + } + /// /// 初始化ViewModel /// @@ -40,6 +50,25 @@ namespace NavisworksTransport.UI.WPF.Views } } + /// + /// 初始化ViewModel(支持统一状态栏) + /// + /// 主ViewModel,用于统一状态栏 + private void InitializeViewModel(LogisticsControlViewModel mainViewModel) + { + try + { + ViewModel = new AnimationControlViewModel(mainViewModel); + DataContext = ViewModel; + LogManager.Info("AnimationControlView ViewModel初始化完成 - 支持统一状态栏"); + } + catch (Exception ex) + { + LogManager.Error($"AnimationControlView ViewModel初始化失败: {ex.Message}", ex); + throw; + } + } + /// /// 清理资源 /// diff --git a/src/UI/WPF/Views/PathEditingView.xaml b/src/UI/WPF/Views/PathEditingView.xaml index c9fb44d..be7370c 100644 --- a/src/UI/WPF/Views/PathEditingView.xaml +++ b/src/UI/WPF/Views/PathEditingView.xaml @@ -181,11 +181,6 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管 Style="{StaticResource SecondaryButtonStyle}"/> - - @@ -195,25 +190,27 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管