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

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]
1. [x] (功能)把三维视图选点光标改成十字形,当失去焦点时,按空格键切换回来。
2. [x] (优化和功能) 用精确几何方式进行通道网格构建,用网格可视化方式确认其正确性
3. [x] (优化) 重写路径优化算法,确保直线和直角转弯,不引入错误路径
### [2025/09/04]

View File

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

View File

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

View File

@ -38,6 +38,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private bool _isLogisticsOnlyMode = false;
private bool _isProcessing = false;
// UI状态管理和命令框架
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
/// <summary>
@ -964,6 +974,53 @@ namespace NavisworksTransport.UI.WPF.ViewModels
#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
/// <summary>

View File

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

View File

@ -259,29 +259,6 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
</StackPanel>
</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>
</ScrollViewer>
</UserControl>

View File

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