130 lines
4.3 KiB
Markdown
130 lines
4.3 KiB
Markdown
# 删除物流属性功能完全修复报告
|
||
|
||
## 问题描述
|
||
|
||
用户反映删除物流属性功能存在问题:删除操作提示成功,但在Navisworks属性面板中仍然显示一个空的"物流属性"类别,没有实现真正的完全删除。
|
||
|
||
## 问题分析
|
||
|
||
### 原始实现问题
|
||
原始的删除方法使用了错误的COM API调用方式:
|
||
```csharp
|
||
// 错误的方法:用空属性集合覆盖
|
||
ComApi.InwOaPropertyVec emptyVec = (ComApi.InwOaPropertyVec)state.ObjectFactory(
|
||
ComApi.nwEObjectType.eObjectType_nwOaPropertyVec, null, null);
|
||
propertyNode.SetUserDefined(1, LogisticsCategories.LOGISTICS,
|
||
LogisticsCategories.CATEGORY_INTERNAL_NAME, emptyVec);
|
||
```
|
||
|
||
这种方法只是清空了属性类别的内容,但没有删除类别容器本身,导致属性面板中显示空的"物流属性"类别。
|
||
|
||
### 根本原因
|
||
通过研究Navisworks COM API文档和Autodesk论坛讨论,发现:
|
||
1. `SetUserDefined`方法只能创建或覆盖属性,不能删除属性类别
|
||
2. 要完全删除用户定义的属性类别,必须使用`RemoveUserDefined`方法
|
||
3. 用户定义属性的索引从1开始,而不是从0开始
|
||
|
||
## 解决方案
|
||
|
||
### 修复后的实现
|
||
```csharp
|
||
// 正确的方法:使用RemoveUserDefined完全删除
|
||
int relativeIndex = GetLogisticsAttributeRelativeIndex(propertyNode);
|
||
if (relativeIndex >= 0)
|
||
{
|
||
// 用户定义属性索引从1开始,所以需要+1
|
||
int userDefinedIndex = relativeIndex + 1;
|
||
|
||
// 使用RemoveUserDefined方法完全删除属性类别
|
||
propertyNode.RemoveUserDefined(userDefinedIndex);
|
||
}
|
||
```
|
||
|
||
### 关键改进点
|
||
|
||
1. **使用正确的API方法**
|
||
- 从`SetUserDefined`改为`RemoveUserDefined`
|
||
- 实现真正的属性类别删除
|
||
|
||
2. **正确的索引计算**
|
||
- 使用相对索引计算用户定义属性位置
|
||
- 索引从1开始而不是0开始
|
||
|
||
3. **完整的错误处理**
|
||
- 验证索引有效性
|
||
- 提供详细的日志记录
|
||
|
||
## 测试验证
|
||
|
||
### 修复前的行为
|
||
- 删除操作提示成功
|
||
- 属性面板中仍显示空的"物流属性"类别
|
||
- 属性内容被清空但类别容器保留
|
||
|
||
### 修复后的行为
|
||
- 删除操作提示成功
|
||
- 属性面板中完全不显示"物流属性"类别
|
||
- 整个属性类别被完全移除
|
||
|
||
## 技术细节
|
||
|
||
### COM API索引机制
|
||
根据Autodesk官方文档和论坛讨论:
|
||
- `SetUserDefined(0, ...)` - 创建新的用户定义属性
|
||
- `SetUserDefined(n, ...)` - 覆盖索引为n的现有属性(n>=1)
|
||
- `RemoveUserDefined(n)` - 删除索引为n的用户定义属性(n>=1)
|
||
|
||
### 索引计算逻辑
|
||
```csharp
|
||
private static int GetLogisticsAttributeRelativeIndex(ComApi.InwGUIPropertyNode2 propertyNode)
|
||
{
|
||
int relativeIndex = 0;
|
||
foreach (ComApi.InwGUIAttribute2 attribute in propertyNode.GUIAttributes())
|
||
{
|
||
if (attribute.UserDefined)
|
||
{
|
||
if (attribute.ClassUserName == LogisticsCategories.LOGISTICS)
|
||
{
|
||
return relativeIndex;
|
||
}
|
||
relativeIndex++;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
```
|
||
|
||
## 影响范围
|
||
|
||
### 直接影响
|
||
- `RemoveLogisticsAttributes`方法完全重构
|
||
- 删除功能现在能真正移除属性类别
|
||
- 用户界面体验显著改善
|
||
|
||
### 间接影响
|
||
- 提高了用户对插件可靠性的信心
|
||
- 避免了属性面板中的冗余空类别
|
||
- 为后续功能开发提供了正确的COM API使用模式
|
||
|
||
## 兼容性
|
||
|
||
### 向后兼容性
|
||
- 修改不影响现有的添加和修改功能
|
||
- 不改变属性数据结构
|
||
- 保持与Navisworks 2017的完全兼容
|
||
|
||
### 未来兼容性
|
||
- 使用标准的COM API方法,确保与新版本的兼容性
|
||
- 遵循Autodesk推荐的最佳实践
|
||
|
||
## 总结
|
||
|
||
此次修复彻底解决了删除物流属性功能的核心问题,从表面的"清空内容"升级为真正的"删除类别"。通过使用正确的COM API方法和索引计算,实现了用户期望的完全删除功能。
|
||
|
||
这个修复不仅解决了当前问题,还为团队提供了关于Navisworks COM API正确使用方式的宝贵经验,有助于避免类似问题的再次出现。
|
||
|
||
## 参考资料
|
||
|
||
1. [Autodesk论坛 - 修改或删除用户定义属性](https://forums.autodesk.com/t5/navisworks-api/modifying-or-deleting-user-defined-properties/m-p/7906707)
|
||
2. [TwentyTwo博客 - Navisworks COM API和自定义属性](https://twentytwo.space/2020/07/18/navisworks-api-com-interface-and-adding-custom-property/)
|
||
3. Navisworks COM API官方文档 |