# NavisworksSelectionHelper 使用指南

## 文件位置

`src/Utils/NavisworksSelectionHelper.cs`

## 用途

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

## 核心方法

### 选择状态查询

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

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

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

### 设置选择

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

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

### 选择文本格式化

```csharp
// 格式化选择状态文本
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
);
```

### 选择事件订阅

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

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

## SelectionStateResult 属性

```csharp
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：检查并显示选择状态

```csharp
// 获取选择状态
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选择状态

```csharp
// 在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：订阅选择变化事件

```csharp
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：程序化设置选择

```csharp
// 选择特定对象
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. **空值处理**：所有方法都处理了空值情况，不会抛出异常
