NavisworksTransport/.agents/skills/project-tools/utils/NavisworksSelectionHelper.md
2026-02-25 02:01:38 +08:00

5.4 KiB
Raw Blame History

NavisworksSelectionHelper 使用指南

文件位置

src/Utils/NavisworksSelectionHelper.cs

用途

提供 Navisworks 选择状态管理帮助功能,包括选择状态查询、格式化显示、事件订阅等。

核心方法

选择状态查询

// 获取当前选择状态信息(同步)
SelectionStateResult result = NavisworksSelectionHelper.GetCurrentSelectionState();

// 获取当前选择状态信息(异步)
SelectionStateResult result = await NavisworksSelectionHelper.GetCurrentSelectionStateAsync();

// 快速检查是否有选中项
bool hasSelection = NavisworksSelectionHelper.HasSelectedItems();

设置选择

// 设置单个模型项为选中状态
bool success = NavisworksSelectionHelper.SetModelSelection(modelItem);

// 设置多个模型项为选中状态
bool success = NavisworksSelectionHelper.SetModelSelection(modelItems);
// 传入 null 或空集合会清除选择

选择文本格式化

// 格式化选择状态文本
string text = NavisworksSelectionHelper.FormatSelectionText(
    count: result.Count,
    selectedItems: result.SelectedItems,
    unitName: "个模型",          // 单位名称
    maxDisplayCount: 3,          // 最多显示名称数量
    maxTotalLength: 80           // 最大总长度
);

// 基于选择结果对象格式化
string text = NavisworksSelectionHelper.FormatSelectionText(
    selectionResult: result,
    unitName: "个对象",
    maxDisplayCount: 3,
    maxTotalLength: 80
);

选择事件订阅

// 订阅选择变化事件
var subscription = NavisworksSelectionHelper.SubscribeToSelectionChanges(
    async (selectionResult) =>
    {
        // 处理选择变化
        LogManager.Info($"选择变化: {selectionResult.Count} 个对象");
    },
    uiStateManager: _uiStateManager  // 可选用于确保UI线程执行
);

// 取消订阅(使用完释放)
subscription.Dispose();

SelectionStateResult 属性

public class SelectionStateResult
{
    public bool Success { get; set; }           // 操作是否成功
    public int Count { get; set; }              // 选择数量
    public List<ModelItem> SelectedItems { get; set; }  // 选择的项目列表
    public bool HasSelection { get; set; }      // 是否有选择
    public string ErrorMessage { get; set; }    // 错误信息(失败时)
}

使用示例

示例1检查并显示选择状态

// 获取选择状态
var result = NavisworksSelectionHelper.GetCurrentSelectionState();

if (!result.Success)
{
    LogManager.Error($"获取选择状态失败: {result.ErrorMessage}");
    return;
}

// 格式化显示
string statusText = NavisworksSelectionHelper.FormatSelectionText(result);
StatusLabel.Text = statusText;

// 启用/禁用相关按钮
EditButton.IsEnabled = result.Count == 1;
DeleteButton.IsEnabled = result.Count > 0;

示例2同步UI选择状态

// 在ViewModel中保持选择状态同步
private void UpdateSelectionState()
{
    var result = NavisworksSelectionHelper.GetCurrentSelectionState();
    
    if (result.Count > 0)
    {
        // 更新属性
        SelectedItems = result.SelectedItems;
        SelectionText = NavisworksSelectionHelper.FormatSelectionText(result);
        
        // 如果有单个选择,显示详细信息
        if (result.Count == 1)
        {
            var item = result.SelectedItems[0];
            SelectedItemName = item.DisplayName;
        }
    }
    else
    {
        SelectedItems = new List<ModelItem>();
        SelectionText = "请选择模型对象";
    }
}

示例3订阅选择变化事件

public class MyViewModel : IDisposable
{
    private SelectionEventSubscription _selectionSubscription;

    public void Initialize()
    {
        // 订阅选择变化
        _selectionSubscription = NavisworksSelectionHelper.SubscribeToSelectionChanges(
            OnSelectionChanged,
            uiStateManager: _uiStateManager
        );
    }

    private async Task OnSelectionChanged(SelectionStateResult result)
    {
        // 此方法在UI线程执行通过uiStateManager
        if (result.HasSelection)
        {
            SelectionText = NavisworksSelectionHelper.FormatSelectionText(result);
            await LoadSelectionDetails(result.SelectedItems);
        }
        else
        {
            SelectionText = "请在主界面中选择需要设置的对象";
        }
    }

    public void Dispose()
    {
        _selectionSubscription?.Dispose();
    }
}

示例4程序化设置选择

// 选择特定对象
var targetItem = FindModelItemById(id);
if (targetItem != null)
{
    bool success = NavisworksSelectionHelper.SetModelSelection(targetItem);
    if (success)
    {
        // 聚焦到该对象
        ViewpointHelper.FocusOnModelItem(targetItem, 45, 0.25);
    }
}

// 清除选择
NavisworksSelectionHelper.SetModelSelection(null);

注意事项

  1. 线程安全GetCurrentSelectionState 等方法是线程安全的但设置选择最好在UI线程执行
  2. 事件处理:选择变化事件使用 async void 内部处理确保不会阻塞UI
  3. 订阅管理:使用 SelectionEventSubscription 模式确保事件正确取消订阅,避免内存泄漏
  4. 格式化限制FormatSelectionText 会自动处理长名称截断和多个项目的显示
  5. 空值处理:所有方法都处理了空值情况,不会抛出异常