优化批量导出进度显示:统一使用Progress API,分离职责

核心改进:
1. ExportLayerToNwd专注导出逻辑,不再管理进度条
2. LayerManagementViewModel统一管理批量导出进度条
3. 状态栏只在开始/结束时显示,避免UI刷新同步问题

修改内容:

**ModelSplitterManager.cs**
- 移除ExportLayerToNwd内的Progress API相关代码
- 移除进度条声明、初始化、更新和清理代码
- 移除用户取消检查(由调用者管理)
- 保留核心导出逻辑:隔离、导出、恢复

**LayerManagementViewModel.cs**
- 在批量导出循环开始前创建Progress API进度条
- 循环中为每个文件更新进度条描述和百分比
- 显示:"正在导出第 X/Y 个分层:分层名"
- 移除循环中的状态栏进度更新(避免UI同步问题)
- 只在结束时更新状态栏最终结果
- finally块确保进度条被正确关闭

最终效果:
-  单文件导出:无进度条,快速完成
-  批量导出:统一的Progress API显示完整进度信息
-  状态栏:只显示开始/结束提示,不跟踪过程进度
-  职责清晰:导出逻辑与进度显示分离

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tian 2025-10-13 12:14:20 +08:00
parent 2e583cb9b6
commit aaebbcad21
2 changed files with 61 additions and 59 deletions

View File

@ -1616,7 +1616,6 @@ namespace NavisworksTransport
return false;
}
Progress progress = null;
try
{
LogManager.Info($"[分层管理器] ========== ExportLayerToNwd开始 ==========");
@ -1647,10 +1646,6 @@ namespace NavisworksTransport
{
try
{
// 🎯 创建进度条
progress = NavisApplication.BeginProgress("导出分层",
$"正在导出 {preview.LayerName}...");
LogManager.Info($"[分层管理器] 在主线程中执行导出操作");
var document = NavisApplication.ActiveDocument;
@ -1661,9 +1656,6 @@ namespace NavisworksTransport
try
{
// 🎯 阶段1隔离显示 (30%)
progress.Update(0.3);
// 直接使用预览结果中的项目,这些已经是展开的完整节点树
var itemsToIsolate = preview.Items;
@ -1679,17 +1671,6 @@ namespace NavisworksTransport
LogManager.Info($"[分层管理器] 隔离显示成功");
// 🎯 检查用户是否取消
if (progress.IsCanceled)
{
LogManager.Info("[分层管理器] 用户取消导出操作");
exportResult = false;
return; // 跳过导出直接到finally块恢复状态
}
// 🎯 阶段2导出文件 (70%)
progress.Update(0.7);
// 创建导出选项
var exportOptions = new Autodesk.Navisworks.Api.NwdExportOptions
{
@ -1706,25 +1687,10 @@ namespace NavisworksTransport
LogManager.Info($"[分层管理器] ExportToNwd API调用完成主线程");
// 🎯 完成 (100%)
progress.Update(1.0);
exportResult = true;
}
finally
{
// 🎯 确保进度条被关闭
if (progress != null)
{
try
{
NavisApplication.EndProgress();
}
catch (Exception progressEx)
{
LogManager.Error($"[分层管理器] 关闭进度条失败: {progressEx.Message}");
}
}
// 恢复原始可见性状态(在主线程中)
try
{

View File

@ -1420,11 +1420,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// 执行选中的分层保存
/// </summary>
private async Task ExecuteSelectedLayersAsync(
ModelSplitterManager modelSplitterManager,
ModelSplitterManager.SplitConfiguration config,
List<ModelSplitterManager.SplitPreviewResult> previewResultsForSave,
ModelSplitterManager modelSplitterManager,
ModelSplitterManager.SplitConfiguration config,
List<ModelSplitterManager.SplitPreviewResult> previewResultsForSave,
CancellationToken cancellationToken)
{
Autodesk.Navisworks.Api.Progress progress = null;
try
{
// 确保输出目录存在
@ -1436,25 +1437,46 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 逐个处理选中的分层
int successCount = 0;
var failedLayers = new List<string>();
// 🎯 创建批量导出进度条(在主线程中)
await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
{
progress = Autodesk.Navisworks.Api.Application.BeginProgress("批量导出分层",
$"准备导出 {previewResultsForSave.Count} 个分层...");
});
for (int i = 0; i < previewResultsForSave.Count; i++)
{
if (cancellationToken.IsCancellationRequested)
var preview = previewResultsForSave[i];
// 🎯 更新进度条描述和百分比(在主线程中)
bool userCanceled = false;
await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
{
if (progress != null && !progress.IsCanceled)
{
// 计算总体进度百分比
double currentProgress = (double)i / previewResultsForSave.Count;
progress.Update(currentProgress);
// 更新进度条描述
Autodesk.Navisworks.Api.Application.EndProgress();
progress = Autodesk.Navisworks.Api.Application.BeginProgress("批量导出分层",
$"正在导出第 {i + 1}/{previewResultsForSave.Count} 个分层:{preview.LayerName}");
}
else if (progress != null && progress.IsCanceled)
{
userCanceled = true;
}
});
// 检查用户是否取消或请求取消
if (userCanceled || cancellationToken.IsCancellationRequested)
{
LogManager.Info($"[LayerManagementViewModel] 用户取消分层操作,已处理 {successCount}/{previewResultsForSave.Count} 个分层");
break;
}
var preview = previewResultsForSave[i];
// 更新进度
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
CurrentOperationText = $"正在处理分层: {preview.LayerName} ({i + 1}/{previewResultsForSave.Count})";
double percentage = (double)(i + 1) * 100 / previewResultsForSave.Count;
UpdateMainStatus($"处理分层 {i + 1}/{previewResultsForSave.Count}: {preview.LayerName}", percentage);
});
try
{
// 处理单个分层
@ -1467,15 +1489,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
string errorMsg = $"分层 {preview.LayerName} 处理失败: {layerEx.Message}";
LogManager.Error($"[LayerManagementViewModel] {errorMsg}");
failedLayers.Add(preview.LayerName);
// 继续处理其他分层,不因单个失败而中断整个进程
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
UpdateMainStatus(errorMsg);
});
}
}
// 生成最终统计信息
string finalMessage = $"分层处理完成:成功 {successCount} 个,失败 {failedLayers.Count} 个";
if (failedLayers.Count > 0)
@ -1487,18 +1503,19 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
LogManager.Info($"[LayerManagementViewModel] {finalMessage}");
}
// 只更新状态栏文字,不更新进度百分比
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
UpdateMainStatus(finalMessage);
});
// 如果所有分层都失败,抛出异常
if (successCount == 0 && previewResultsForSave.Count > 0)
{
throw new InvalidOperationException($"所有选中的分层处理都失败了,共 {previewResultsForSave.Count} 个分层");
}
LogManager.Info($"[LayerManagementViewModel] 分层执行完成:成功 {successCount}/{previewResultsForSave.Count}");
}
catch (Exception ex)
@ -1506,6 +1523,25 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogManager.Error($"[LayerManagementViewModel] 分层执行失败: {ex.Message}");
throw;
}
finally
{
// 🎯 确保进度条被关闭(在主线程中)
if (progress != null)
{
await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
{
try
{
Autodesk.Navisworks.Api.Application.EndProgress();
LogManager.Info("[LayerManagementViewModel] 批量导出进度条已关闭");
}
catch (Exception progressEx)
{
LogManager.Error($"[LayerManagementViewModel] 关闭进度条失败: {progressEx.Message}");
}
});
}
}
}
/// <summary>