增加底部状态栏,统一提示消息和进度条显示

This commit is contained in:
tian 2025-09-07 15:52:56 +08:00
parent f32c367fd0
commit ba01624152
7 changed files with 172 additions and 72 deletions

View File

@ -2,9 +2,17 @@
## 功能点 ## 功能点
### [2025/09/07]
1. [ ] (功能)增加插件系统参数配置和管理
2. [ ] (功能)增加物流属性自定义
3. [x] (功能)增加底部状态栏,统一提示消息和进度条显示
### [2025/09/05] ### [2025/09/05]
1. [x] (功能)把三维视图选点光标改成十字形,当失去焦点时,按空格键切换回来。 1. [x] (功能)把三维视图选点光标改成十字形,当失去焦点时,按空格键切换回来。
2. [x] (优化和功能) 用精确几何方式进行通道网格构建,用网格可视化方式确认其正确性
3. [x] (优化) 重写路径优化算法,确保直线和直角转弯,不引入错误路径
### [2025/09/04] ### [2025/09/04]

View File

@ -16,7 +16,7 @@ NavisworksTransport 主控制面板 - 采用与其他视图一致的Navisworks 2
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="clr-namespace:NavisworksTransport.UI.WPF.Views" xmlns:views="clr-namespace:NavisworksTransport.UI.WPF.Views"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="700" d:DesignWidth="480"> d:DesignHeight="700" d:DesignWidth="480">
<UserControl.Resources> <UserControl.Resources>
@ -25,6 +25,9 @@ NavisworksTransport 主控制面板 - 采用与其他视图一致的Navisworks 2
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/> <ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
<!-- 转换器资源 -->
<BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>
</ResourceDictionary> </ResourceDictionary>
</UserControl.Resources> </UserControl.Resources>
@ -78,17 +81,37 @@ NavisworksTransport 主控制面板 - 采用与其他视图一致的Navisworks 2
Background="#FFF8FBFF" Background="#FFF8FBFF"
Margin="10,5,10,10" Margin="10,5,10,10"
Padding="12,8"> Padding="12,8">
<StackPanel Orientation="Horizontal" <Grid>
HorizontalAlignment="Right"> <Grid.ColumnDefinitions>
<Button Content="帮助" <ColumnDefinition Width="*"/>
Click="HelpButton_Click" <ColumnDefinition Width="Auto"/>
Style="{StaticResource SecondaryButtonStyle}" </Grid.ColumnDefinitions>
ToolTip="查看插件使用说明和操作指南"/>
<Button Content="关于" <!-- 左侧:状态信息 -->
Click="AboutButton_Click" <Grid Grid.Column="0" Margin="8,6,20,6">
Style="{StaticResource SecondaryButtonStyle}" <ProgressBar Height="20"
ToolTip="查看插件版本信息和开发者信息"/> IsIndeterminate="{Binding IsProcessing}"
</StackPanel> Visibility="{Binding IsProcessing, Converter={StaticResource BoolToVisConverter}}"/>
<TextBlock Text="{Binding StatusText}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="10"
Margin="10,0,0,0"/>
</Grid>
<!-- 右侧:原有按钮 -->
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Button Content="帮助"
Click="HelpButton_Click"
Style="{StaticResource SecondaryButtonStyle}"
ToolTip="查看插件使用说明和操作指南"/>
<Button Content="关于"
Click="AboutButton_Click"
Style="{StaticResource SecondaryButtonStyle}"
ToolTip="查看插件版本信息和开发者信息"/>
</StackPanel>
</Grid>
</Border> </Border>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -61,8 +61,8 @@ namespace NavisworksTransport.UI.WPF
// 将分层管理视图添加到主界面 // 将分层管理视图添加到主界面
LayerManagementContent.Content = _layerManagementView; LayerManagementContent.Content = _layerManagementView;
// 创建类别设置视图 // 创建类别设置视图传入主ViewModel引用以启用统一状态栏
_modelSettingsView = new ModelSettingsView(); _modelSettingsView = new ModelSettingsView(ViewModel);
// 将类别设置视图添加到主界面 // 将类别设置视图添加到主界面
ModelSettingsContent.Content = _modelSettingsView; ModelSettingsContent.Content = _modelSettingsView;

View File

@ -38,6 +38,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private bool _isLogisticsOnlyMode = false; private bool _isLogisticsOnlyMode = false;
private bool _isProcessing = false;
// UI状态管理和命令框架 // UI状态管理和命令框架
private readonly UIStateManager _uiStateManager; private readonly UIStateManager _uiStateManager;
@ -192,6 +193,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
} }
/// <summary>
/// 是否正在处理中(用于统一状态栏进度条显示)
/// </summary>
public bool IsProcessing
{
get => _isProcessing;
set => SetProperty(ref _isProcessing, value);
}
#region #region
/// <summary> /// <summary>
@ -964,6 +974,53 @@ namespace NavisworksTransport.UI.WPF.ViewModels
#endregion #endregion
#region
/// <summary>
/// 更新统一状态栏信息(简单版本,不显示进度条)
/// </summary>
/// <param name="message">状态消息</param>
public void UpdateStatus(string message)
{
SafeExecute(() =>
{
StatusText = message ?? "就绪";
IsProcessing = false; // 简单状态更新不显示进度条
}, "更新统一状态栏", runOnUIThread: true);
}
/// <summary>
/// 更新统一状态栏信息(完整版本)
/// </summary>
/// <param name="message">状态消息</param>
/// <param name="progress">进度值 (0-100),默认不显示进度条</param>
/// <param name="isProcessing">是否正在处理中(显示进度条动画)</param>
public void UpdateStatus(string message, double progress = -1, bool? isProcessing = null)
{
SafeExecute(() =>
{
StatusText = message ?? "就绪";
if (progress >= 0)
{
AnimationProgress = Math.Max(0, Math.Min(100, progress));
}
if (isProcessing.HasValue)
{
IsProcessing = isProcessing.Value;
}
}, "更新统一状态栏", runOnUIThread: true);
}
/// <summary>
/// 重置状态栏到默认状态
/// </summary>
public void ResetStatus()
{
UpdateStatus("插件已就绪");
}
#endregion
#region #region
/// <summary> /// <summary>

View File

@ -32,6 +32,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
#region #region
private readonly UIStateManager _uiStateManager; private readonly UIStateManager _uiStateManager;
private readonly LogisticsControlViewModel _mainViewModel;
// 选择事件订阅管理器 // 选择事件订阅管理器
private SelectionEventSubscription _selectionEventSubscription; private SelectionEventSubscription _selectionEventSubscription;
@ -45,7 +46,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private bool _isProcessing; private bool _isProcessing;
private string _selectedModelsText = "请在主界面中选择需要设置的模型"; private string _selectedModelsText = "请在主界面中选择需要设置的模型";
private string _statusText = "就绪";
private string _selectedCategory = "通道"; private string _selectedCategory = "通道";
private bool _isTraversable = true; private bool _isTraversable = true;
private int _priority = 5; private int _priority = 5;
@ -90,14 +90,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
set => SetPropertyThreadSafe(ref _selectedModelsText, value); set => SetPropertyThreadSafe(ref _selectedModelsText, value);
} }
/// <summary>
/// 状态文本
/// </summary>
public string StatusText
{
get => _statusText;
set => SetPropertyThreadSafe(ref _statusText, value);
}
/// <summary> /// <summary>
/// 可用类别集合 - 使用线程安全集合 /// 可用类别集合 - 使用线程安全集合
@ -281,12 +273,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
#region - 使 #region - 使
public ModelSettingsViewModel() : base() public ModelSettingsViewModel(LogisticsControlViewModel mainViewModel = null) : base()
{ {
try try
{ {
// 获取UI状态管理器实例 // 获取UI状态管理器实例和主ViewModel引用
_uiStateManager = UIStateManager.Instance; _uiStateManager = UIStateManager.Instance;
_mainViewModel = mainViewModel;
// 验证关键组件是否正常初始化 // 验证关键组件是否正常初始化
if (_uiStateManager == null) if (_uiStateManager == null)
@ -310,7 +303,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{ {
LogManager.Error($"ModelSettingsViewModel构造函数异常: {ex.Message}", ex); LogManager.Error($"ModelSettingsViewModel构造函数异常: {ex.Message}", ex);
StatusText = "初始化失败,请检查日志"; UpdateMainStatus("初始化失败,请检查日志");
throw; throw;
} }
} }
@ -363,7 +356,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
IsProcessing = true; IsProcessing = true;
StatusText = "正在检查模型选择..."; UpdateMainStatus("正在检查模型选择...", -1, true);
}); });
try try
@ -377,12 +370,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (selectionResult.Success) if (selectionResult.Success)
{ {
SelectedModelsText = NavisworksSelectionHelper.FormatSelectionText(selectionResult, "个模型"); SelectedModelsText = NavisworksSelectionHelper.FormatSelectionText(selectionResult, "个模型");
StatusText = "检查完成"; UpdateMainStatus("检查完成");
} }
else else
{ {
SelectedModelsText = selectionResult.ErrorMessage ?? "检查选择状态失败"; SelectedModelsText = selectionResult.ErrorMessage ?? "检查选择状态失败";
StatusText = "检查失败"; UpdateMainStatus("检查失败");
} }
// 🔧 修复:刷新所有与选择相关的命令状态(包括清除属性按钮) // 🔧 修复:刷新所有与选择相关的命令状态(包括清除属性按钮)
@ -400,7 +393,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
SelectedModelsText = "检查选择状态异常"; SelectedModelsText = "检查选择状态异常";
StatusText = $"检查失败: {ex.Message}"; UpdateMainStatus($"检查失败: {ex.Message}");
}); });
} }
finally finally
@ -422,9 +415,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
IsProcessing = true; IsProcessing = true;
StatusText = "正在设置物流属性..."; UpdateMainStatus("正在设置物流属性...", -1, true);
}); });
try try
{ {
// 2. 纯业务逻辑执行后台线程不使用UIStateManager // 2. 纯业务逻辑执行后台线程不使用UIStateManager
@ -473,7 +467,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 3. 结果UI更新 // 3. 结果UI更新
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
StatusText = result.Message; UpdateMainStatus(result.Message);
if (result.Success) if (result.Success)
{ {
@ -485,6 +479,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
}); });
// 如果设置成功,异步刷新物流模型列表 // 如果设置成功,异步刷新物流模型列表
if (result.Success) if (result.Success)
{ {
@ -507,8 +502,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 异常UI更新 // 异常UI更新
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
StatusText = $"设置属性出错: {ex.Message}"; UpdateMainStatus($"设置属性出错: {ex.Message}");
}); });
} }
finally finally
{ {
@ -517,6 +513,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{ {
IsProcessing = false; IsProcessing = false;
}); });
} }
} }
@ -529,7 +526,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
IsProcessing = true; IsProcessing = true;
StatusText = "正在清除物流属性..."; UpdateMainStatus("正在清除物流属性...", -1, true);
}); });
try try
@ -565,7 +562,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 3. 结果UI更新 // 3. 结果UI更新
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
StatusText = result.Message; UpdateMainStatus(result.Message);
if (result.Success) if (result.Success)
{ {
@ -599,7 +596,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 异常UI更新 // 异常UI更新
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
StatusText = $"清除属性出错: {ex.Message}"; UpdateMainStatus($"清除属性出错: {ex.Message}");
}); });
} }
finally finally
@ -621,7 +618,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
IsProcessing = true; IsProcessing = true;
StatusText = "正在刷新物流模型列表..."; UpdateMainStatus("正在刷新物流模型列表...", -1, true);
}); });
try try
@ -670,11 +667,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{ {
LogisticsModels.Add(model); LogisticsModels.Add(model);
} }
StatusText = $"已刷新物流模型列表,共 {result.Count} 个模型"; UpdateMainStatus($"已刷新物流模型列表,共 {result.Count} 个模型");
} }
else else
{ {
StatusText = "刷新物流模型列表失败"; UpdateMainStatus("刷新物流模型列表失败");
} }
}); });
@ -688,7 +685,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
LogisticsModels.Clear(); LogisticsModels.Clear();
StatusText = $"刷新列表出错: {ex.Message}"; UpdateMainStatus($"刷新列表出错: {ex.Message}");
}); });
} }
finally finally
@ -715,7 +712,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
HeightLimit = 3.0; HeightLimit = 3.0;
SpeedLimit = 0.8; SpeedLimit = 0.8;
StatusText = "已重置为默认值"; UpdateMainStatus("已重置为默认值");
LogManager.Info("已重置类别设置为默认值"); LogManager.Info("已重置类别设置为默认值");
}); });
} }
@ -867,7 +864,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
RefreshAllCommands(); RefreshAllCommands();
StatusText = "分层属性设置已就绪"; UpdateMainStatus("分层属性设置已就绪");
}); });
} }
catch (Exception ex) catch (Exception ex)
@ -875,7 +872,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogManager.Error($"[ModelSettingsViewModel] 初始化失败: {ex.Message}"); LogManager.Error($"[ModelSettingsViewModel] 初始化失败: {ex.Message}");
await _uiStateManager.ExecuteUIUpdateAsync(() => await _uiStateManager.ExecuteUIUpdateAsync(() =>
{ {
StatusText = "初始化失败,请检查日志"; UpdateMainStatus("初始化失败,请检查日志");
}); });
} }
} }
@ -912,12 +909,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
model.IsVisible = true; model.IsVisible = true;
} }
StatusText = "显示所有元素"; UpdateMainStatus("显示所有元素");
LogManager.Info("切换到显示全部模式"); LogManager.Info("切换到显示全部模式");
} }
else else
{ {
StatusText = $"显示全部失败: {result.Message}"; UpdateMainStatus($"显示全部失败: {result.Message}");
LogManager.Error($"显示全部失败: {result.Message}"); LogManager.Error($"显示全部失败: {result.Message}");
} }
} }
@ -972,7 +969,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
var totalVisibleItems = itemsToKeepVisible.Count; var totalVisibleItems = itemsToKeepVisible.Count;
StatusText = $"仅显示物流元素 ({logisticsItems.Count} 个物流节点,{totalVisibleItems} 个可见元素)"; UpdateMainStatus($"仅显示物流元素 ({logisticsItems.Count} 个物流节点,{totalVisibleItems} 个可见元素)");
LogManager.Info($"切换到仅显示物流模式: 找到 {logisticsItems.Count} 个物流节点,{totalVisibleItems} 个可见元素"); LogManager.Info($"切换到仅显示物流模式: 找到 {logisticsItems.Count} 个物流节点,{totalVisibleItems} 个可见元素");
} }
} }
@ -1219,6 +1216,44 @@ namespace NavisworksTransport.UI.WPF.ViewModels
System.Windows.Input.CommandManager.InvalidateRequerySuggested(); System.Windows.Input.CommandManager.InvalidateRequerySuggested();
} }
/// <summary>
/// 更新统一状态栏(简单版本,不显示进度条)
/// </summary>
private void UpdateMainStatus(string message)
{
try
{
// 如果有主ViewModel引用更新统一状态栏
if (_mainViewModel != null)
{
_mainViewModel.UpdateStatus(message);
}
}
catch (Exception ex)
{
LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex);
}
}
/// <summary>
/// 更新统一状态栏(完整版本,支持进度条)
/// </summary>
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 #endregion
#region #region

View File

@ -259,29 +259,6 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
</StackPanel> </StackPanel>
</Border> </Border>
<!-- 状态显示区域 -->
<Border BorderBrush="#FFE0E0E0" BorderThickness="1" CornerRadius="0" Padding="12"
Visibility="{Binding IsProcessing, Converter={StaticResource BoolToVisConverter}}">
<StackPanel>
<TextBlock Text="{Binding StatusText}"
FontWeight="SemiBold"
Margin="0,0,0,5"/>
<ProgressBar IsIndeterminate="True"
Height="16"
Margin="0,0,0,5"/>
<TextBlock Text="正在处理,请稍候..."
Style="{StaticResource StatusTextStyle}"/>
</StackPanel>
</Border>
<!-- 底部状态栏 -->
<Border BorderBrush="#FFE0E0E0" BorderThickness="1" CornerRadius="0" Padding="8"
Background="#FFF8F9FA" Margin="0,5,0,0">
<TextBlock Text="{Binding StatusText}"
Style="{StaticResource StatusTextStyle}"
HorizontalAlignment="Center"/>
</Border>
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>
</UserControl> </UserControl>

View File

@ -10,14 +10,14 @@ namespace NavisworksTransport.UI.WPF.Views
/// </summary> /// </summary>
public partial class ModelSettingsView : UserControl public partial class ModelSettingsView : UserControl
{ {
public ModelSettingsView() public ModelSettingsView(LogisticsControlViewModel mainViewModel = null)
{ {
InitializeComponent(); InitializeComponent();
try try
{ {
// 设置数据上下文为新的ViewModel // 设置数据上下文为新的ViewModel传入主ViewModel引用
DataContext = new ModelSettingsViewModel(); DataContext = new ModelSettingsViewModel(mainViewModel);
LogManager.Info("ModelSettingsView已初始化使用新的ModelSettingsViewModel"); LogManager.Info("ModelSettingsView已初始化使用新的ModelSettingsViewModel");
} }
catch (System.Exception ex) catch (System.Exception ex)