NavisworksTransport/doc/bugfixes/层属性选择同步问题修复报告.md

196 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 楼层属性设置功能选择同步问题修复报告
## 问题描述
在NavisworksTransport插件的分层管理功能中当用户在Navisworks中选择树节点时
- **正常现象**:选择集保存区域显示"已选择1个项目"
- **问题现象**:楼层属性设置区域的状态信息没有变化,设置按钮不能点击
## 问题根因分析
### 1. 事件订阅对比
#### 选择集保存功能(正常工作)
- **位置**`LogisticsControlPanel.xaml.cs`
- **事件订阅**`NavisApplication.ActiveDocument.CurrentSelection.Changed += OnSelectionChanged;`
- **处理逻辑**:在`OnSelectionChanged`中调用`UpdateCurrentSelectionAsync()`更新主ViewModel的选择状态
#### 楼层属性设置功能(有问题)
- **位置**`LayerManagementViewModel.cs`
- **事件订阅****没有订阅Navisworks选择变化事件**
- **初始化**:只在`InitializeAsync()`中调用一次`RefreshSelectionAsync()`
### 2. 事件处理流程差异
**正常流程(选择集保存)**
```
Navisworks选择变化
→ LogisticsControlPanel.OnSelectionChanged
→ ViewModel.UpdateCurrentSelectionAsync()
→ 更新"已选择X个项目"状态
```
**问题流程(楼层属性设置)**
```
Navisworks选择变化
→ (无事件处理)
→ 状态不更新
→ 按钮保持不可用状态
```
## 解决方案
### 1. 添加选择事件订阅
在`LayerManagementViewModel.cs`中添加选择事件处理机制:
```csharp
// 构造函数中订阅事件
SubscribeToSelectionEvents();
// 添加订阅方法
private void SubscribeToSelectionEvents()
{
try
{
if (Autodesk.Navisworks.Api.Application.ActiveDocument?.CurrentSelection != null)
{
Autodesk.Navisworks.Api.Application.ActiveDocument.CurrentSelection.Changed += OnNavisworksSelectionChanged;
LogManager.Info("[LayerManagementViewModel] 已订阅Navisworks选择变化事件");
}
}
catch (Exception ex)
{
LogManager.Error($"[LayerManagementViewModel] 订阅选择事件失败: {ex.Message}", ex);
}
}
```
### 2. 实现选择变化处理器
```csharp
private async void OnNavisworksSelectionChanged(object sender, EventArgs e)
{
try
{
// 使用UIStateManager确保在正确的线程上执行UI更新
await _uiStateManager.ExecuteUIUpdateAsync(async () =>
{
await UpdateFloorAttributeSelectionStateAsync();
});
}
catch (Exception ex)
{
LogManager.Error($"[LayerManagementViewModel] 处理选择变化事件异常: {ex.Message}", ex);
}
}
```
### 3. 专门的楼层属性状态更新方法
```csharp
private async Task UpdateFloorAttributeSelectionStateAsync()
{
try
{
// 纯业务逻辑执行(后台线程)
var result = await Task.Run(() =>
{
try
{
var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
if (document?.CurrentSelection?.SelectedItems?.Count > 0)
{
var selectedCount = document.CurrentSelection.SelectedItems.Count;
return new { Success = true, Count = selectedCount, Message = $"已选择 {selectedCount} 个模型" };
}
else
{
return new { Success = true, Count = 0, Message = "请在主界面中选择需要设置的模型" };
}
}
catch (Exception ex)
{
return new { Success = false, Count = 0, Message = $"检查选择状态失败: {ex.Message}" };
}
});
// UI更新
SelectedModelsText = result.Message;
// 刷新命令状态
OnPropertyChanged(nameof(HasSelectedItems));
OnPropertyChanged(nameof(HasSelectedModels));
OnPropertyChanged(nameof(CanSetFloorAttribute));
OnPropertyChanged(nameof(CanClearFloorAttribute));
LogManager.Info($"[LayerManagementViewModel] 楼层属性选择状态已更新: {result.Message}");
}
catch (Exception ex)
{
LogManager.Error($"[LayerManagementViewModel] 更新楼层属性选择状态异常: {ex.Message}", ex);
SelectedModelsText = "检查选择状态异常";
}
}
```
### 4. 资源清理
在`Dispose()`方法中添加事件取消订阅:
```csharp
// 取消Navisworks选择变化事件订阅
UnsubscribeFromSelectionEvents();
```
## 修复验证
### 1. UI数据绑定验证
确认XAML中的绑定正确
- `SelectedModelsText` → 显示选择状态
- `CanSetFloorAttribute` → 设置按钮可用性
- `CanClearFloorAttribute` → 清除按钮可用性
### 2. 预期修复结果
修复后,当用户选择树节点时:
- ✅ 楼层属性设置区域的状态信息应该正确更新
- ✅ 设置楼层属性的按钮应该变为可点击状态
- ✅ 状态提示应该显示当前选择的对象信息
- ✅ 与选择集保存功能保持同步,无冲突
## 技术要点
### 1. 线程安全
- 使用`UIStateManager.ExecuteUIUpdateAsync()`确保UI更新在正确线程执行
- 业务逻辑在后台线程中执行避免阻塞UI
### 2. 事件处理模式
- 遵循项目的统一事件处理架构
- 业务逻辑与UI分离符合MVVM模式
### 3. 错误处理
- 完善的异常处理和日志记录
- 优雅的错误状态显示
## 影响范围
### 修改的文件
- `src/UI/WPF/ViewModels/LayerManagementViewModel.cs`
### 涉及的功能
- 楼层属性设置功能的用户体验改进
- 不影响现有选择集保存等其他功能
### 风险评估
- **低风险**修改仅限于LayerManagementViewModel内部
- **向后兼容**不改变现有API或接口
- **独立性**:与其他功能模块解耦
## 总结
此修复通过为LayerManagementViewModel添加Navisworks选择变化事件监听解决了楼层属性设置功能中状态不同步的问题。修复遵循了项目既有的架构模式确保了代码质量和系统稳定性。
修复后的楼层属性设置功能将具备与选择集保存功能相同的响应性和用户体验,提升了整体插件的一致性和可用性。