完善了自定义分层属性,提供三种预定义属性

This commit is contained in:
tian 2025-08-27 02:37:25 +08:00
parent 944f83bd7e
commit 0de9de617f
7 changed files with 675 additions and 128 deletions

View File

@ -143,6 +143,255 @@ namespace NavisworksTransport.Core
} }
} }
/// <summary>
/// 设置单个分层属性,保留其他现有属性
/// </summary>
/// <param name="item">模型项</param>
/// <param name="attributeType">属性类型:楼层、区域、子系统</param>
/// <param name="attributeValue">属性值</param>
/// <returns>操作是否成功</returns>
public bool SetSingleLayerAttribute(ModelItem item, string attributeType, string attributeValue)
{
if (item == null || string.IsNullOrEmpty(attributeType) || string.IsNullOrEmpty(attributeValue))
{
LogManager.Error("[FloorAttributeManager] 设置单个分层属性失败:参数无效");
return false;
}
try
{
LogManager.Info($"[FloorAttributeManager] 开始设置模型 {item.DisplayName} 的{attributeType}属性: {attributeValue}");
return ExecuteWithUIThread(() =>
{
// 获取COM API状态对象
ComApi.InwOpState10 state = ComApiBridge.State;
// 转换ModelItem为COM路径
ComApi.InwOaPath comPath = ComApiBridge.ToInwOaPath(item);
// 获取属性节点
ComApi.InwGUIPropertyNode2 propertyNode =
(ComApi.InwGUIPropertyNode2)state.GetGUIPropertyNode(comPath, false);
// 获取现有的所有分层属性值
var existingFloorLevel = GetFloorLevelFromProperty(propertyNode);
var existingZone = GetZoneFromProperty(propertyNode);
var existingSubSystem = GetSubSystemFromProperty(propertyNode);
// 根据属性类型更新对应的值
string finalFloorLevel = existingFloorLevel;
string finalZone = existingZone;
string finalSubSystem = existingSubSystem;
switch (attributeType)
{
case "楼层":
finalFloorLevel = attributeValue;
break;
case "区域":
finalZone = attributeValue;
break;
case "子系统":
finalSubSystem = attributeValue;
break;
default:
LogManager.Error($"[FloorAttributeManager] 不支持的属性类型: {attributeType}");
return false;
}
// 创建新的属性分类,包含所有属性(现有的+新设置的)
ComApi.InwOaPropertyVec propertyCategory =
(ComApi.InwOaPropertyVec)state.ObjectFactory(
ComApi.nwEObjectType.eObjectType_nwOaPropertyVec, null, null);
// 添加楼层属性(如果有值)
if (!string.IsNullOrEmpty(finalFloorLevel))
{
AddFloorProperty(state, propertyCategory, FLOOR_LEVEL_DISPLAY_NAME,
finalFloorLevel, FLOOR_LEVEL_PROPERTY);
}
// 添加区域属性(如果有值)
if (!string.IsNullOrEmpty(finalZone))
{
AddFloorProperty(state, propertyCategory, ZONE_DISPLAY_NAME,
finalZone, ZONE_PROPERTY);
}
// 添加子系统属性(如果有值)
if (!string.IsNullOrEmpty(finalSubSystem))
{
AddFloorProperty(state, propertyCategory, SUBSYSTEM_DISPLAY_NAME,
finalSubSystem, SUBSYSTEM_PROPERTY);
}
// 检查是否已存在分层属性,获取正确的索引
int existingFloorAttributeIndex = GetFloorAttributeIndex(propertyNode);
if (existingFloorAttributeIndex >= 0)
{
// 存在分层属性时,使用正确的索引进行修改
int updateIndex = existingFloorAttributeIndex + 1;
propertyNode.SetUserDefined(updateIndex, FLOOR_CATEGORY, FLOOR_CATEGORY_INTERNAL, propertyCategory);
LogManager.Info($"[FloorAttributeManager] ✅ 成功更新{attributeType}属性 (索引={updateIndex})");
}
else
{
// 不存在分层属性时使用索引0创建新属性
propertyNode.SetUserDefined(0, FLOOR_CATEGORY, FLOOR_CATEGORY_INTERNAL, propertyCategory);
LogManager.Info($"[FloorAttributeManager] ✅ 成功创建{attributeType}属性 (索引=0)");
}
return true;
});
}
catch (Exception ex)
{
LogManager.Error($"[FloorAttributeManager] ❌ 设置{attributeType}属性失败,错误: {ex.Message}", ex);
return false;
}
}
/// <summary>
/// 从属性节点获取楼层属性值
/// </summary>
private string GetFloorLevelFromProperty(ComApi.InwGUIPropertyNode2 propertyNode)
{
try
{
foreach (ComApi.InwGUIAttribute2 attribute in propertyNode.GUIAttributes())
{
if (attribute.ClassUserName == FLOOR_CATEGORY)
{
foreach (ComApi.InwOaProperty property in attribute.Properties())
{
if (property.name == FLOOR_LEVEL_PROPERTY)
{
return property.value?.ToString();
}
}
}
}
}
catch (Exception ex)
{
LogManager.Debug($"[FloorAttributeManager] 获取楼层属性异常: {ex.Message}");
}
return null;
}
/// <summary>
/// 从属性节点获取区域属性值
/// </summary>
private string GetZoneFromProperty(ComApi.InwGUIPropertyNode2 propertyNode)
{
try
{
foreach (ComApi.InwGUIAttribute2 attribute in propertyNode.GUIAttributes())
{
if (attribute.ClassUserName == FLOOR_CATEGORY)
{
foreach (ComApi.InwOaProperty property in attribute.Properties())
{
if (property.name == ZONE_PROPERTY)
{
return property.value?.ToString();
}
}
}
}
}
catch (Exception ex)
{
LogManager.Debug($"[FloorAttributeManager] 获取区域属性异常: {ex.Message}");
}
return null;
}
/// <summary>
/// 从属性节点获取子系统属性值
/// </summary>
private string GetSubSystemFromProperty(ComApi.InwGUIPropertyNode2 propertyNode)
{
try
{
foreach (ComApi.InwGUIAttribute2 attribute in propertyNode.GUIAttributes())
{
if (attribute.ClassUserName == FLOOR_CATEGORY)
{
foreach (ComApi.InwOaProperty property in attribute.Properties())
{
if (property.name == SUBSYSTEM_PROPERTY)
{
return property.value?.ToString();
}
}
}
}
}
catch (Exception ex)
{
LogManager.Debug($"[FloorAttributeManager] 获取子系统属性异常: {ex.Message}");
}
return null;
}
/// <summary>
/// 获取模型项的区域属性值
/// </summary>
public string GetZoneAttribute(ModelItem item)
{
if (item == null) return null;
try
{
return ExecuteWithUIThread(() =>
{
ComApi.InwOpState10 state = ComApiBridge.State;
ComApi.InwOaPath comPath = ComApiBridge.ToInwOaPath(item);
ComApi.InwGUIPropertyNode2 propertyNode =
(ComApi.InwGUIPropertyNode2)state.GetGUIPropertyNode(comPath, false);
return GetZoneFromProperty(propertyNode);
});
}
catch (Exception ex)
{
LogManager.Error($"[FloorAttributeManager] 获取区域属性失败:{ex.Message}", ex);
return null;
}
}
/// <summary>
/// 获取模型项的子系统属性值
/// </summary>
public string GetSubSystemAttribute(ModelItem item)
{
if (item == null) return null;
try
{
return ExecuteWithUIThread(() =>
{
ComApi.InwOpState10 state = ComApiBridge.State;
ComApi.InwOaPath comPath = ComApiBridge.ToInwOaPath(item);
ComApi.InwGUIPropertyNode2 propertyNode =
(ComApi.InwGUIPropertyNode2)state.GetGUIPropertyNode(comPath, false);
return GetSubSystemFromProperty(propertyNode);
});
}
catch (Exception ex)
{
LogManager.Error($"[FloorAttributeManager] 获取子系统属性失败:{ex.Message}", ex);
return null;
}
}
/// <summary> /// <summary>
/// 获取对象的楼层标识,支持继承查询 /// 获取对象的楼层标识,支持继承查询
/// </summary> /// </summary>

View File

@ -2758,17 +2758,12 @@ namespace NavisworksTransport
if (renderPlugin != null) if (renderPlugin != null)
{ {
// 清空所有现有的路径点标记 // 清空所有现有的路径点标记
renderPlugin.ClearAllMarkers(); renderPlugin.ClearAllPaths();
// 绘制选中路径的所有路径点 // 使用新的统一路径可视化方法
var sortedPoints = selectedPath.GetSortedPoints(); renderPlugin.RenderPath(selectedPath);
for (int i = 0; i < sortedPoints.Count; i++)
{
var point = sortedPoints[i];
renderPlugin.AddCircleMarker(point.Position, point.Type, i + 1);
}
LogManager.Info($"已绘制路径: {selectedPath.Name},包含 {sortedPoints.Count} 个路径点和连线"); LogManager.Info($"已绘制路径: {selectedPath.Name},包含 {selectedPath.Points.Count} 个路径点和连线");
} }
else else
{ {
@ -2851,7 +2846,7 @@ namespace NavisworksTransport
var renderPlugin = PathPointRenderPlugin.Instance; var renderPlugin = PathPointRenderPlugin.Instance;
if (renderPlugin != null) if (renderPlugin != null)
{ {
renderPlugin.ClearAllMarkers(); renderPlugin.ClearAllPaths();
LogManager.Info("已清空所有路径可视化"); LogManager.Info("已清空所有路径可视化");
} }
} }

View File

@ -597,7 +597,6 @@ namespace NavisworksTransport
if (marker != null) if (marker != null)
{ {
_pathPointMarkers.Remove(marker); _pathPointMarkers.Remove(marker);
_renderPlugin?.RemovePathPointMarker(marker);
LogManager.Info($"已从3D中移除路径点标记: {point.Name}"); LogManager.Info($"已从3D中移除路径点标记: {point.Name}");
} }
} }
@ -1164,14 +1163,11 @@ namespace NavisworksTransport
{ {
lastPoint.Type = PathPointType.EndPoint; lastPoint.Type = PathPointType.EndPoint;
lastPoint.Name = GeneratePointName(PathPointType.EndPoint); lastPoint.Name = GeneratePointName(PathPointType.EndPoint);
// 更新3D路径可视化 // 更新3D路径可视化
if (_renderPlugin != null) // 重新渲染整个路径以反映类型变更
{ _renderPlugin?.RenderPath(CurrentRoute);
// 重新渲染整个路径以反映类型变更
_renderPlugin.RenderPath(CurrentRoute);
}
LogManager.Info($"已自动设置最后一个点为终点: {lastPoint.Name}"); LogManager.Info($"已自动设置最后一个点为终点: {lastPoint.Name}");
} }
} }
@ -2025,7 +2021,7 @@ namespace NavisworksTransport
// 清理资源 // 清理资源
if (_renderPlugin != null) if (_renderPlugin != null)
{ {
_renderPlugin.CleanUp(); _renderPlugin.ClearAllPaths();
_renderPlugin = null; _renderPlugin = null;
} }

View File

@ -890,58 +890,6 @@ namespace NavisworksTransport
private static DateTime _lastRefreshTime = DateTime.MinValue; private static DateTime _lastRefreshTime = DateTime.MinValue;
#endregion #endregion
#region
/// <summary>
/// 清除路径标记(兼容性方法)
/// </summary>
public void ClearPathMarkers()
{
ClearAllMarkers();
}
/// <summary>
/// 移除路径点标记(兼容性方法)
/// </summary>
/// <param name="pathPoint">路径点</param>
/// <returns>是否成功移除</returns>
public bool RemovePathPointMarker(PathPoint pathPoint)
{
if (pathPoint?.Position != null)
{
return RemoveMarkerAt(pathPoint.Position, 1.0);
}
return false;
}
/// <summary>
/// 移除路径点标记(兼容性方法)
/// </summary>
/// <param name="marker">路径点标记</param>
/// <returns>是否成功移除</returns>
public bool RemovePathPointMarker(PathPointMarker marker)
{
if (marker?.PathPoint?.Position != null)
{
return RemoveMarkerAt(marker.PathPoint.Position, 1.0);
}
return false;
}
#endregion
#region
/// <summary>
/// 清理资源
/// </summary>
public void CleanUp()
{
ClearAllMarkers();
}
#endregion
} }
/// <summary> /// <summary>

View File

@ -83,6 +83,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private string _selectedFloorLevel = "F1"; private string _selectedFloorLevel = "F1";
private string _selectedZone = ""; private string _selectedZone = "";
private string _selectedSubSystem = ""; private string _selectedSubSystem = "";
// 新的分层参数系统相关字段
private string _selectedLayerParameter = "楼层";
private string _selectedParameterValue = "F1";
private bool _showLayerAttributeInfo = false;
private string _currentLayerAttributeInfo = string.Empty;
private bool _showFloorAttributeInfo = false; private bool _showFloorAttributeInfo = false;
private string _currentFloorAttributeInfo = ""; private string _currentFloorAttributeInfo = "";
private bool _showCancelButton = false; private bool _showCancelButton = false;
@ -326,6 +331,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (SetPropertyThreadSafe(ref _currentSelectionText, value)) if (SetPropertyThreadSafe(ref _currentSelectionText, value))
{ {
OnPropertyChanged(nameof(HasSelectedItems)); OnPropertyChanged(nameof(HasSelectedItems));
OnPropertyChanged(nameof(CanSetLayerAttribute));
OnPropertyChanged(nameof(CanClearLayerAttribute));
} }
} }
} }
@ -442,6 +449,81 @@ namespace NavisworksTransport.UI.WPF.ViewModels
get => _selectedSubSystem; get => _selectedSubSystem;
set => SetPropertyThreadSafe(ref _selectedSubSystem, value); set => SetPropertyThreadSafe(ref _selectedSubSystem, value);
} }
/// <summary>
/// 选中的分层参数类型(楼层、区域、子系统)
/// </summary>
public string SelectedLayerParameter
{
get => _selectedLayerParameter;
set
{
if (SetPropertyThreadSafe(ref _selectedLayerParameter, value))
{
// 当分层参数类型改变时,自动更新参数值为合适的默认值
switch (value)
{
case "楼层":
SelectedParameterValue = "F1";
break;
case "区域":
SelectedParameterValue = "北区";
break;
case "子系统":
SelectedParameterValue = "消防系统";
break;
default:
SelectedParameterValue = "F1";
break;
}
// 通知相关属性更新
OnPropertyChanged(nameof(CanSetLayerAttribute));
}
}
}
/// <summary>
/// 分层参数值
/// </summary>
public string SelectedParameterValue
{
get => _selectedParameterValue;
set
{
if (SetPropertyThreadSafe(ref _selectedParameterValue, value))
{
// 通知相关属性更新
OnPropertyChanged(nameof(CanSetLayerAttribute));
}
}
}
/// <summary>
/// 是否显示分层属性信息
/// </summary>
public bool ShowLayerAttributeInfo
{
get => _showLayerAttributeInfo;
set => SetPropertyThreadSafe(ref _showLayerAttributeInfo, value);
}
/// <summary>
/// 当前分层属性信息
/// </summary>
public string CurrentLayerAttributeInfo
{
get => _currentLayerAttributeInfo;
set => SetPropertyThreadSafe(ref _currentLayerAttributeInfo, value);
}
/// <summary>
/// 分层参数选项集合
/// </summary>
public ObservableCollection<string> LayerParameterOptions { get; } = new ObservableCollection<string>
{
"楼层",
"区域",
"子系统"
};
/// <summary> /// <summary>
/// 是否显示楼层属性信息 /// 是否显示楼层属性信息
@ -487,6 +569,50 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{ {
get => HasSelectedModels && !string.IsNullOrEmpty(SelectedFloorLevel) && IsNotProcessing; get => HasSelectedModels && !string.IsNullOrEmpty(SelectedFloorLevel) && IsNotProcessing;
} }
/// <summary>
/// 是否可以设置分层属性
/// </summary>
public bool CanSetLayerAttribute => IsNotProcessing && !string.IsNullOrWhiteSpace(SelectedParameterValue) && HasSelectedItems;
/// <summary>
/// 是否可以清除分层属性
/// </summary>
public bool CanClearLayerAttribute
{
get
{
try
{
if (IsProcessing || !HasSelectedItems)
return false;
// 检查选中的模型是否有任何分层属性
var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
if (document?.CurrentSelection?.SelectedItems?.Count > 0)
{
var floorManager = new FloorAttributeManager();
var selection = document.CurrentSelection.SelectedItems;
foreach (var item in selection)
{
// 使用GetFloorLevel方法检查是否有楼层属性
var floorLevel = floorManager.GetFloorLevel(item);
if (!string.IsNullOrEmpty(floorLevel))
{
return true;
}
}
}
return false;
}
catch (Exception ex)
{
LogManager.Error($"[LayerManagementViewModel] 检查清除分层属性条件异常: {ex.Message}", ex);
return false;
}
}
}
/// <summary> /// <summary>
/// 是否可以清除楼层属性 /// 是否可以清除楼层属性
@ -553,6 +679,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public ICommand SetFloorAttributeCommand { get; private set; } public ICommand SetFloorAttributeCommand { get; private set; }
public ICommand ClearFloorAttributeCommand { get; private set; } public ICommand ClearFloorAttributeCommand { get; private set; }
public ICommand ViewFloorAttributeCommand { get; private set; } public ICommand ViewFloorAttributeCommand { get; private set; }
// 新的分层属性命令
public ICommand SetLayerAttributeCommand { get; private set; }
public ICommand ClearLayerAttributeCommand { get; private set; }
public ICommand ViewLayerAttributeCommand { get; private set; }
#endregion #endregion
@ -672,6 +803,19 @@ namespace NavisworksTransport.UI.WPF.ViewModels
async () => await ViewFloorAttributeAsync(), async () => await ViewFloorAttributeAsync(),
() => HasSelectedItems); () => HasSelectedItems);
// 新的分层属性命令初始化
SetLayerAttributeCommand = new RelayCommand(
async () => await SetLayerAttributeAsync(),
() => CanSetLayerAttribute);
ClearLayerAttributeCommand = new RelayCommand(
async () => await ClearLayerAttributeAsync(),
() => CanClearLayerAttribute);
ViewLayerAttributeCommand = new RelayCommand(
async () => await ViewLayerAttributeAsync(),
() => HasSelectedItems);
LogManager.Info("分层管理命令初始化完成 - 使用统一Command Pattern框架"); LogManager.Info("分层管理命令初始化完成 - 使用统一Command Pattern框架");
}, "初始化命令"); }, "初始化命令");
} }
@ -2200,6 +2344,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
OnPropertyChanged(nameof(CanPreviewSplit)); OnPropertyChanged(nameof(CanPreviewSplit));
OnPropertyChanged(nameof(CanExecuteSplit)); OnPropertyChanged(nameof(CanExecuteSplit));
OnPropertyChanged(nameof(HasSelectedItems)); OnPropertyChanged(nameof(HasSelectedItems));
OnPropertyChanged(nameof(CanSetFloorAttribute));
OnPropertyChanged(nameof(CanClearFloorAttribute));
OnPropertyChanged(nameof(CanSetLayerAttribute));
OnPropertyChanged(nameof(CanClearLayerAttribute));
} }
/// <summary> /// <summary>
@ -2667,6 +2815,245 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
} }
/// <summary>
/// 设置分层属性
/// </summary>
private async Task SetLayerAttributeAsync()
{
await SafeExecuteAsync(async () =>
{
if (string.IsNullOrWhiteSpace(SelectedParameterValue))
{
CurrentOperationText = "请输入参数值";
return;
}
var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
if (document?.CurrentSelection?.SelectedItems?.Count == 0)
{
CurrentOperationText = "请先选择要设置属性的模型对象";
return;
}
IsProcessing = true;
ShowCancelButton = false;
CurrentOperationText = "正在设置分层属性...";
var totalItems = document.CurrentSelection.SelectedItems.Count;
var processedItems = 0;
try
{
var floorManager = new FloorAttributeManager();
var selectedItems = document.CurrentSelection.SelectedItems.ToList();
foreach (var item in selectedItems)
{
// 使用新的SetSingleLayerAttribute方法只设置指定的属性类型
bool result = floorManager.SetSingleLayerAttribute(item, SelectedLayerParameter, SelectedParameterValue);
if (result)
{
processedItems++;
}
ProgressPercentage = (double)processedItems / totalItems * 100;
}
CurrentOperationText = $"分层属性设置完成,成功设置 {processedItems}/{totalItems} 个对象的{SelectedLayerParameter}属性:{SelectedParameterValue}";
LogManager.Info($"[LayerManagementViewModel] 成功设置分层属性: {SelectedLayerParameter}={SelectedParameterValue},影响对象数:{processedItems}");
// 刷新选中模型信息
await RefreshSelectionAsync();
}
catch (Exception ex)
{
LogManager.Error($"[LayerManagementViewModel] 设置分层属性异常: {ex.Message}", ex);
CurrentOperationText = $"设置分层属性时发生错误:{ex.Message}";
}
finally
{
IsProcessing = false;
ProgressPercentage = 0;
}
}, "设置分层属性");
}
/// <summary>
/// 清除分层属性
/// </summary>
private async Task ClearLayerAttributeAsync()
{
await SafeExecuteAsync(async () =>
{
var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
if (document?.CurrentSelection?.SelectedItems?.Count == 0)
{
CurrentOperationText = "请先选择要清除属性的模型对象";
return;
}
IsProcessing = true;
ShowCancelButton = false;
CurrentOperationText = "正在清除分层属性...";
var totalItems = document.CurrentSelection.SelectedItems.Count;
var processedItems = 0;
try
{
var floorManager = new FloorAttributeManager();
var selectedItems = document.CurrentSelection.SelectedItems.ToList();
foreach (var item in selectedItems)
{
try
{
bool result = floorManager.ClearFloorAttribute(item);
if (result)
{
processedItems++;
}
}
catch (Exception ex)
{
LogManager.Error($"清除模型 {item.DisplayName} 的分层属性失败:{ex.Message}");
}
ProgressPercentage = (double)(processedItems + 1) / totalItems * 100;
}
CurrentOperationText = $"分层属性清除完成,成功清除 {processedItems}/{totalItems} 个对象的分层属性";
LogManager.Info($"[LayerManagementViewModel] 成功清除分层属性,影响对象数:{processedItems}");
// 刷新选中模型信息
await RefreshSelectionAsync();
ShowLayerAttributeInfo = false;
}
catch (Exception ex)
{
LogManager.Error($"[LayerManagementViewModel] 清除分层属性异常: {ex.Message}", ex);
CurrentOperationText = $"清除分层属性时发生错误:{ex.Message}";
}
finally
{
IsProcessing = false;
ProgressPercentage = 0;
}
}, "清除分层属性");
}
/// <summary>
/// 查看分层属性
/// </summary>
private async Task ViewLayerAttributeAsync()
{
try
{
var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
if (document?.CurrentSelection?.SelectedItems == null || document.CurrentSelection.SelectedItems.Count == 0)
{
// 使用UI线程更新状态
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
ShowLayerAttributeInfo = true;
CurrentLayerAttributeInfo = "未选择任何模型项,请先选择要查看的模型";
});
return;
}
// 在后台线程执行业务逻辑
var result = await Task.Run<dynamic>(() =>
{
try
{
var floorManager = new FloorAttributeManager();
var selectedItems = document.CurrentSelection.SelectedItems.ToList();
var totalItems = selectedItems.Count;
var attributeInfo = new System.Text.StringBuilder();
attributeInfo.AppendLine($"选中对象总数:{totalItems}");
attributeInfo.AppendLine();
var hasAttributeCount = 0;
foreach (var item in selectedItems.Take(30)) // 增加显示数量到30个
{
try
{
string itemName = item.DisplayName ?? "未命名";
var itemAttributes = new List<string>();
// 获取楼层属性
var floorLevel = floorManager.GetFloorLevel(item);
if (!string.IsNullOrEmpty(floorLevel))
{
itemAttributes.Add($"楼层={floorLevel}");
}
// 获取区域属性
var zone = floorManager.GetZoneAttribute(item);
if (!string.IsNullOrEmpty(zone))
{
itemAttributes.Add($"区域={zone}");
}
// 获取子系统属性
var subsystem = floorManager.GetSubSystemAttribute(item);
if (!string.IsNullOrEmpty(subsystem))
{
itemAttributes.Add($"子系统={subsystem}");
}
if (itemAttributes.Count > 0)
{
hasAttributeCount++;
attributeInfo.AppendLine($"✅ {itemName}: {string.Join(", ", itemAttributes)}");
}
else
{
attributeInfo.AppendLine($"❌ {itemName}: 无分层属性");
}
}
catch (Exception ex)
{
attributeInfo.AppendLine($"⚠️ {item.DisplayName}: 查询失败 - {ex.Message}");
}
}
if (selectedItems.Count > 30)
{
attributeInfo.AppendLine($"... 还有 {selectedItems.Count - 30} 个模型项未显示");
}
return new { Success = true, Info = attributeInfo.ToString(), Count = totalItems, HasAttributeCount = hasAttributeCount };
}
catch (Exception ex)
{
return new { Success = false, Info = $"查询失败: {ex.Message}", Count = 0, HasAttributeCount = 0 };
}
});
// 在UI线程更新结果
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
CurrentLayerAttributeInfo = result.Info;
ShowLayerAttributeInfo = true;
});
LogManager.Info($"[LayerManagementViewModel] 分层属性查看完成,共 {result.Count} 个模型项,其中 {result.HasAttributeCount} 个有分层属性");
}
catch (Exception ex)
{
LogManager.Error($"[LayerManagementViewModel] 查看分层属性异常: {ex.Message}", ex);
// 在UI线程显示错误信息
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
CurrentLayerAttributeInfo = $"查看操作异常: {ex.Message}";
ShowLayerAttributeInfo = true;
});
}
}
#endregion #endregion
} }
} }

View File

@ -33,10 +33,10 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10"> <ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
<StackPanel> <StackPanel>
<!-- 区域1: 楼层属性设置 --> <!-- 区域1: 自定义分层属性 -->
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12"> <Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
<StackPanel> <StackPanel>
<Label Content="楼层属性设置" Style="{StaticResource SectionHeaderStyle}"/> <Label Content="自定义分层属性" Style="{StaticResource SectionHeaderStyle}"/>
<!-- 模型选择状态显示 --> <!-- 模型选择状态显示 -->
<Grid Margin="0,5,0,15"> <Grid Margin="0,5,0,15">
@ -52,19 +52,19 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
Margin="0,0,0,5"/> Margin="0,0,0,5"/>
</Grid> </Grid>
<!-- 层属性设置功能 --> <!-- 自定义分层属性设置功能 -->
<Expander Header="楼层信息设置" <Expander Header="自定义分层属性"
IsExpanded="False" IsExpanded="False"
Margin="0,5,0,0"> Margin="0,5,0,0">
<StackPanel Margin="10,10,0,5"> <StackPanel Margin="10,10,0,5">
<!-- 使用提示信息 --> <!-- 使用提示信息 -->
<TextBlock Text="为选中的模型设置楼层信息,用于后续的分层导出和路径规划" <TextBlock Text="为选中的模型设置自定义分层属性,用于后续的分层导出和路径规划"
Style="{StaticResource StatusTextStyle}" Style="{StaticResource StatusTextStyle}"
Foreground="#FF666666" Foreground="#FF666666"
Margin="0,0,0,10" Margin="0,0,0,10"
TextWrapping="Wrap"/> TextWrapping="Wrap"/>
<!-- 第一行:楼层标识 --> <!-- 第一行:分层属性选择 -->
<Grid Margin="0,0,0,10"> <Grid Margin="0,0,0,10">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
@ -74,76 +74,48 @@ NavisworksTransport 分层管理页签视图 - 重构优化版本
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="楼层:" Style="{StaticResource ParameterLabelStyle}"/> <Label Grid.Column="0" Content="分层属性:" Style="{StaticResource ParameterLabelStyle}"/>
<ComboBox Grid.Column="1" <ComboBox Grid.Column="1"
x:Name="FloorLevelComboBox" x:Name="LayerParameterComboBox"
Text="{Binding SelectedFloorLevel}" ItemsSource="{Binding LayerParameterOptions}"
IsEditable="True" SelectedItem="{Binding SelectedLayerParameter}"
Margin="5,2" IsEnabled="{Binding IsNotProcessing}" Margin="5,2" IsEnabled="{Binding IsNotProcessing}"
ToolTip="选择或输入楼层标识如F1、F2、B1等"> ToolTip="选择分层属性类型">
<ComboBoxItem>F1</ComboBoxItem>
<ComboBoxItem>F2</ComboBoxItem>
<ComboBoxItem>F3</ComboBoxItem>
<ComboBoxItem>F4</ComboBoxItem>
<ComboBoxItem>F5</ComboBoxItem>
<ComboBoxItem>B1</ComboBoxItem>
<ComboBoxItem>B2</ComboBoxItem>
<ComboBoxItem>B3</ComboBoxItem>
</ComboBox> </ComboBox>
<Label Grid.Column="2" Content="区域:" VerticalAlignment="Center" Margin="15,0,0,0"/> <Label Grid.Column="2" Content="属性值:" VerticalAlignment="Center" Margin="15,0,0,0"/>
<TextBox Grid.Column="3" <TextBox Grid.Column="3"
Text="{Binding SelectedZone}" Text="{Binding SelectedParameterValue}"
Style="{StaticResource ParameterInputStyle}" Style="{StaticResource ParameterInputStyle}"
ToolTip="可选:区域标识,如北区、南区等"/> ToolTip="输入属性值如F1、F2、北区、南区等"/>
</Grid>
<!-- 第二行:建筑标识 -->
<Grid Margin="0,0,0,15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="子系统:" Style="{StaticResource ParameterLabelStyle}"/>
<TextBox Grid.Column="1"
Text="{Binding SelectedSubSystem}"
Style="{StaticResource ParameterInputStyle}"
ToolTip="可选:子系统标识"/>
<TextBlock Grid.Column="2"
Text="(选填)"
Style="{StaticResource StatusTextStyle}"
VerticalAlignment="Center"
Margin="10,0,0,0"/>
</Grid> </Grid>
<!-- 操作按钮区域 --> <!-- 操作按钮区域 -->
<StackPanel Orientation="Horizontal" <StackPanel Orientation="Horizontal"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Margin="0,5,0,5"> Margin="0,5,0,5">
<Button Content="设置层属性" <Button Content="设置分层属性"
Style="{StaticResource ActionButtonStyle}" Style="{StaticResource ActionButtonStyle}"
Command="{Binding SetFloorAttributeCommand}" Command="{Binding SetLayerAttributeCommand}"
IsEnabled="{Binding CanSetFloorAttribute}" IsEnabled="{Binding CanSetLayerAttribute}"
ToolTip="为选中的模型设置层属性"/> ToolTip="为选中的模型设置分层属性"/>
<Button Content="清除层属性" <Button Content="清除分层属性"
Style="{StaticResource ActionButtonStyle}" Style="{StaticResource ActionButtonStyle}"
Command="{Binding ClearFloorAttributeCommand}" Command="{Binding ClearLayerAttributeCommand}"
IsEnabled="{Binding CanClearFloorAttribute}" IsEnabled="{Binding CanClearLayerAttribute}"
ToolTip="清除选中模型的层属性"/> ToolTip="清除选中模型的分层属性"/>
<Button Content="查看层属性" <Button Content="查看分层属性"
Style="{StaticResource SecondaryButtonStyle}" Style="{StaticResource SecondaryButtonStyle}"
Command="{Binding ViewFloorAttributeCommand}" Command="{Binding ViewLayerAttributeCommand}"
IsEnabled="{Binding HasSelectedItems}" IsEnabled="{Binding HasSelectedItems}"
ToolTip="查看选中模型的当前层属性"/> ToolTip="查看选中模型的当前层属性"/>
</StackPanel> </StackPanel>
<!-- 层属性显示区域 --> <!-- 层属性显示区域 -->
<GroupBox Header="当前层属性" Margin="0,10,0,0" <GroupBox Header="当前层属性" Margin="0,10,0,0"
Visibility="{Binding ShowFloorAttributeInfo, Converter={StaticResource BoolToVisConverter}}"> Visibility="{Binding ShowLayerAttributeInfo, Converter={StaticResource BoolToVisConverter}}">
<StackPanel Margin="10"> <StackPanel Margin="10">
<TextBlock Text="{Binding CurrentFloorAttributeInfo}" <TextBlock Text="{Binding CurrentLayerAttributeInfo}"
Style="{StaticResource StatusTextStyle}" Style="{StaticResource StatusTextStyle}"
TextWrapping="Wrap" TextWrapping="Wrap"
Margin="0,5"/> Margin="0,5"/>