原生树无法扩展，自定义别名树面板就是唯一可靠的载体。在那个面板里，你可以完全自由地定制右键菜单，比如：
表格  菜单项	功能
编辑别名	就地改名
清除别名	恢复原名
在视图中聚焦	3D 定位
批量设置前缀	对当前节点及其子节点统一加前缀
导出此分支	只导出当前节点下的别名 CSV

实际工作流画面
想象你的屏幕布局：
plain
┌─────────────────┬──────────────────┐
│  内置 Selection │   3D 模型视图     │
│     Tree        │                  │
│  (原始名字)      │   [框选操作区]    │
│                 │                  │
├─────────────────┤                  │
│   别名导航树      │                  │
│  (自定义名字)    │                  │
│                 │                  │
└─────────────────┴──────────────────┘
找东西：用户在别名树里看到"二楼-空调水管-123"，一眼认出。
点一下：别名树高亮，3D 视图聚焦到那根管子，内置 Selection Tree 也同步跳转到对应节点。
反过来：用户在 3D 视图里框选一根管子，内置树亮了，别名树也自动展开高亮显示"二楼-空调水管-123"。
用户完全不需要记住原始命名规则，两个面板互相印证。
一个小提醒：首次加载性能
如果模型有 10万+ 节点，且你需要一次性把所有别名加载进字典，建议在插件初始化时做一个后台线程 + 进度条：
csharp
// 异步构建别名字典，避免 UI 卡死
private async void BuildAliasMapAsync()
{
    await Task.Run(() =>
    {
        var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
        // 遍历所有节点生成 Guid->Alias 映射
        // ...
    });
    RefreshTree();
}
结论
这个"双面板联动"方案是性价比最高的落地方式：
没有破坏 Navisworks 原生结构（稳定、升级兼容）
没有重写复杂树控件（100 多行代码搞定）
** alias 数据完全由你掌控**（Excel、数据库、规则生成均可）
用户体验几乎等同于原生支持别名

下面是可直接编译的完整方案，共 6 个文件。核心思路：
AliasTreePane：Navisworks DockPane 外壳。
AliasTreeControl：WPF 别名树面板，支持悬停铅笔编辑、顶部快捷栏、右键菜单、CSV 导入导出、自动生成前缀别名。
双向联动：点击别名树选中模型；在 3D 视图/内置树选中后，别名树自动展开并高亮。
延迟加载：大模型下只加载可见节点，展开时才填充子节点。

1. AliasNode.cs（数据模型）

using Autodesk.Navisworks.Api;
using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace AliasTree
{
    public class AliasNode : INotifyPropertyChanged
    {
        public ModelItem ModelItem { get; set; }
        public Guid Guid => ModelItem?.InstanceGuid ?? Guid.Empty;

        private string _alias;
        public string Alias
        {
            get => _alias;
            set
            {
                _alias = value;
                OnPropertyChanged(nameof(Alias));
                OnPropertyChanged(nameof(DisplayText));
            }
        }

        private bool _isEditing;
        public bool IsEditing
        {
            get => _isEditing;
            set { _isEditing = value; OnPropertyChanged(nameof(IsEditing)); }
        }

        public string DisplayText => string.IsNullOrEmpty(Alias) ? (ModelItem?.DisplayName ?? "未命名") : Alias;

        public List<<AliasNode> Children { get; set; } = new List<<AliasNode>();

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string name) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

2. AliasTreePlugin.cs（插件入口）

using Autodesk.Navisworks.Api.Plugins;

namespace AliasTree
{
    [Plugin("AliasTreePane", "YourCompany", DisplayName = "别名导航树")]
    [DockPanePlugin(400, 600, FixedSize = false)]
    public class AliasTreePlugin : DockPanePlugin
    {
        public override Pane CreatePane() => new AliasTreePane();
    }
}

3. AliasTreePane.cs（Pane 外壳）

using Autodesk.Navisworks.Api.Plugins;

namespace AliasTree
{
    public class AliasTreePane : Pane
    {
        public AliasTreePane()
        {
            this.Content = new AliasTreeControl();
        }
    }
}

4. AliasTreeControl.xaml（界面布局）

<UserControl x:Class="AliasTree.AliasTreeControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:AliasTree">
    <DockPanel>
        <!-- 顶部快捷栏 -->
        <ToolBar DockPanel.Dock="Top" Height="32">
            <TextBlock Text="当前选中:" VerticalAlignment="Center" Margin="4,0"/>
            <TextBlock x:Name="TbCurrentName" Text="无" VerticalAlignment="Center" 
                       FontWeight="Bold" Margin="4,0" MaxWidth="150" TextTrimming="CharacterEllipsis"/>
            <Separator/>
            <TextBox x:Name="TxtQuickAlias" Width="120" ToolTip="输入别名后回车" 
                     KeyDown="TxtQuickAlias_KeyDown"/>
            <Button Content="✓ 保存" Click="BtnQuickSave_Click" ToolTip="为当前选中节点保存别名"/>
            <Separator/>
            <Button Content="导出CSV" Click="BtnExport_Click"/>
            <Button Content="导入CSV" Click="BtnImport_Click"/>
            <Separator/>
            <Button Content="自动生成" Click="BtnAutoGen_Click" ToolTip="按父节点路径自动生成别名"/>
        </ToolBar>

        <!-- 别名树 -->
        <TreeView x:Name="AliasTreeView" 
                  VirtualizingPanel.IsVirtualizing="True"
                  VirtualizingPanel.VirtualizationMode="Recycling">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:AliasNode}" ItemsSource="{Binding Children}">
                    <StackPanel Orientation="Horizontal" Margin="0,1">
                        <!-- 显示模式：无别名时灰色斜体显示原名 -->
                        <TextBlock Text="{Binding DisplayText}" VerticalAlignment="Center" MinWidth="60">
                            <TextBlock.Style>
                                <Style TargetType="TextBlock">
                                    <Setter Property="Foreground" Value="Black"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding Alias}" Value="">
                                            <Setter Property="Foreground" Value="Gray"/>
                                            <Setter Property="FontStyle" Value="Italic"/>
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding Alias}" Value="{x:Null}">
                                            <Setter Property="Foreground" Value="Gray"/>
                                            <Setter Property="FontStyle" Value="Italic"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBlock.Style>
                        </TextBlock>
                        
                        <!-- 编辑模式：默认隐藏，IsEditing=True 时显示 -->
                        <TextBox Text="{Binding Alias, UpdateSourceTrigger=PropertyChanged}" 
                                 Width="120" Visibility="Collapsed" VerticalAlignment="Center"
                                 KeyDown="AliasTextBox_KeyDown" LostFocus="AliasTextBox_LostFocus">
                            <TextBox.Style>
                                <Style TargetType="TextBox">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsEditing}" Value="True">
                                            <Setter Property="Visibility" Value="Visible"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBox.Style>
                        </TextBox>

                        <!-- 铅笔图标：鼠标悬停该行时显示 -->
                        <Button Content="✎" Margin="4,0,0,0" Padding="2,0" 
                                Click="BtnEdit_Click" Tag="{Binding}" VerticalAlignment="Center">
                            <Button.Style>
                                <Style TargetType="Button">
                                    <Setter Property="Visibility" Value="Collapsed"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=IsMouseOver}" Value="True">
                                            <Setter Property="Visibility" Value="Visible"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Button.Style>
                        </Button>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
            
            <TreeView.ItemContainerStyle>
                <Style TargetType="TreeViewItem">
                    <Setter Property="IsExpanded" Value="False"/>
                    <EventSetter Event="Expanded" Handler="TreeViewItem_Expanded"/>
                    <EventSetter Event="Selected" Handler="TreeViewItem_Selected"/>
                    <Setter Property="ContextMenu">
                        <Setter.Value>
                            <ContextMenu>
                                <MenuItem Header="编辑别名" Click="CtxEdit_Click"/>
                                <MenuItem Header="清除别名" Click="CtxClear_Click"/>
                                <Separator/>
                                <MenuItem Header="在视图中聚焦" Click="CtxFocus_Click"/>
                            </ContextMenu>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TreeView.ItemContainerStyle>
        </TreeView>
    </DockPanel>
</UserControl>

5. AliasTreeControl.xaml.cs（核心逻辑）

using Autodesk.Navisworks.Api;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace AliasTree
{
    public partial class AliasTreeControl : UserControl
    {
        private Dictionary<<Guid, string> _aliasMap = new Dictionary<<Guid, string>();
        private List<<AliasNode> _rootNodes = new List<<AliasNode>();

        public AliasTreeControl()
        {
            InitializeComponent();
            AliasTreeView.ItemsSource = _rootNodes;

            Autodesk.Navisworks.Api.Application.MainDocumentChanged += (s, e) =>
            {
                HookSelection();
                RefreshTree();
            };

            HookSelection();
            RefreshTree();
        }

        private void HookSelection()
        {
            var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            if (doc != null)
                doc.CurrentSelection.Changed += OnNavisSelectionChanged;
        }

        // ==================== 树构建与延迟加载 ====================
        private void RefreshTree()
        {
            _rootNodes.Clear();
            var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            if (doc == null) return;

            foreach (var root in doc.Models.RootItems)
            {
                var node = CreateAliasNode(root, true);
                if (node != null) _rootNodes.Add(node);
            }
        }

        private AliasNode CreateAliasNode(ModelItem item, bool lazyLoad)
        {
            if (item == null) return null;

            var node = new AliasNode
            {
                ModelItem = item,
                Alias = GetAlias(item.InstanceGuid)
            };

            if (item.Children.Any())
            {
                if (lazyLoad)
                {
                    // 添加占位节点，使 TreeView 显示展开箭头
                    node.Children.Add(new AliasNode { ModelItem = null, Alias = "Loading..." });
                }
                else
                {
                    foreach (var child in item.Children)
                    {
                        var childNode = CreateAliasNode(child, true);
                        if (childNode != null) node.Children.Add(childNode);
                    }
                }
            }
            return node;
        }

        private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource is TreeViewItem tvi && tvi.DataContext is AliasNode node)
            {
                // 检查是否是占位节点（尚未加载真实子节点）
                if (node.Children.Count == 1 && node.Children[0].ModelItem == null)
                {
                    node.Children.Clear();
                    if (node.ModelItem != null)
                    {
                        foreach (var child in node.ModelItem.Children)
                        {
                            var childNode = CreateAliasNode(child, true);
                            if (childNode != null) node.Children.Add(childNode);
                        }
                    }
                }
            }
        }

        // ==================== 双向联动 ====================
        private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource is TreeViewItem tvi && tvi.DataContext is AliasNode node)
            {
                if (node.ModelItem == null) return;

                var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
                if (doc == null) return;

                var coll = new ModelItemCollection();
                coll.Add(node.ModelItem);
                doc.CurrentSelection.SelectedItems = coll;
            }
        }

        private void OnNavisSelectionChanged(object sender, EventArgs e)
        {
            var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            if (doc == null) return;

            var selected = doc.CurrentSelection.SelectedItems;

            Dispatcher.BeginInvoke(new Action(() =>
            {
                if (selected.Count == 1)
                {
                    var item = selected.First();
                    TbCurrentName.Text = item.DisplayName;
                    TbCurrentName.Tag = item;
                    ExpandAndHighlight(item.InstanceGuid);
                }
                else
                {
                    TbCurrentName.Text = selected.Count > 1 ? $"({selected.Count} 个选中)" : "无";
                    TbCurrentName.Tag = null;
                }
            }));
        }

        private void ExpandAndHighlight(Guid guid)
        {
            // 找到路径
            var path = new List<<AliasNode>();
            if (!FindPath(_rootNodes, guid, path)) return;

            // 逐层展开并加载数据
            ItemsControl current = AliasTreeView;
            foreach (var node in path)
            {
                // 强制加载延迟加载的节点数据
                if (node.Children.Count == 1 && node.Children[0].ModelItem == null)
                {
                    node.Children.Clear();
                    if (node.ModelItem != null)
                    {
                        foreach (var child in node.ModelItem.Children)
                        {
                            var childNode = CreateAliasNode(child, true);
                            if (childNode != null) node.Children.Add(childNode);
                        }
                    }
                }

                if (current is TreeViewItem tvi)
                {
                    tvi.IsExpanded = true;
                    tvi.UpdateLayout();
                }

                current = (TreeViewItem)current.ItemContainerGenerator.ContainerFromItem(node);
                if (current == null) break; // 虚拟化下可能未生成，中断
            }

            // 高亮目标
            if (current is TreeViewItem target && target.DataContext is AliasNode targetNode && targetNode.Guid == guid)
            {
                target.IsSelected = true;
                target.BringIntoView();
            }
        }

        private bool FindPath(List<<AliasNode> nodes, Guid guid, List<<AliasNode> path)
        {
            foreach (var n in nodes)
            {
                path.Add(n);
                if (n.Guid == guid) return true;
                if (FindPath(n.Children, guid, path)) return true;
                path.RemoveAt(path.Count - 1);
            }
            return false;
        }

        // ==================== 内联编辑（铅笔图标） ====================
        private void BtnEdit_Click(object sender, RoutedEventArgs e)
        {
            if ((sender as Button)?.Tag is not AliasNode node) return;
            ClearAllEditing(_rootNodes);
            node.IsEditing = true;

            Dispatcher.BeginInvoke(new Action(() =>
            {
                var container = AliasTreeView.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem;
                if (container == null) return;
                var txt = FindVisualChild<TextBox>(container);
                if (txt != null)
                {
                    txt.Focus();
                    txt.SelectAll();
                }
            }), System.Windows.Threading.DispatcherPriority.Render);
        }

        private void AliasTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
                (sender as TextBox)?.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
        }

        private void AliasTextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if ((sender as TextBox)?.DataContext is not AliasNode node) return;
            SaveAlias(node.Guid, node.Alias);
            node.IsEditing = false;
            node.Alias = GetAlias(node.Guid); // 同步最终值
        }

        // ==================== 右键菜单 ====================
        private void CtxEdit_Click(object sender, RoutedEventArgs e)
        {
            if (AliasTreeView.SelectedItem is AliasNode node)
                BtnEdit_Click(new Button { Tag = node }, null);
        }

        private void CtxClear_Click(object sender, RoutedEventArgs e)
        {
            if (AliasTreeView.SelectedItem is not AliasNode node) return;
            SaveAlias(node.Guid, null);
            node.Alias = null;
        }

        private void CtxFocus_Click(object sender, RoutedEventArgs e)
        {
            if (AliasTreeView.SelectedItem is not AliasNode node || node.ModelItem == null) return;

            var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            if (doc == null) return;

            var coll = new ModelItemCollection();
            coll.Add(node.ModelItem);
            doc.CurrentSelection.SelectedItems = coll;
            doc.ActiveView.FocusOnItem(node.ModelItem, false);
        }

        // ==================== 顶部快捷栏 ====================
        private void TxtQuickAlias_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter) BtnQuickSave_Click(null, null);
        }

        private void BtnQuickSave_Click(object sender, RoutedEventArgs e)
        {
            if (TbCurrentName.Tag is not ModelItem item) return;
            if (string.IsNullOrWhiteSpace(TxtQuickAlias.Text)) return;

            SaveAlias(item.InstanceGuid, TxtQuickAlias.Text.Trim());
            TxtQuickAlias.Clear();
            RefreshNodeDisplay(item.InstanceGuid);
        }

        // ==================== 自动生成别名 ====================
        private void BtnAutoGen_Click(object sender, RoutedEventArgs e)
        {
            var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            if (doc == null) return;

            var gen = new AliasGenerator();
            var generated = gen.Generate(doc.Models.RootItems.FirstOrDefault(), "/");

            foreach (var kv in generated)
                _aliasMap[kv.Key] = kv.Value;

            RefreshTree();
        }

        // ==================== CSV 导入导出 ====================
        private void BtnExport_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new SaveFileDialog { Filter = "CSV 文件|*.csv", Title = "导出别名映射" };
            if (dlg.ShowDialog() != true) return;

            var lines = new List<string> { "Guid,OriginalName,Alias" };
            foreach (var kv in _aliasMap)
            {
                var item = Autodesk.Navisworks.Api.Application.ActiveDocument?.Models.FindItemByGuid(kv.Key);
                string orig = item?.DisplayName ?? "";
                lines.Add($"{kv.Key},\"{orig}\",\"{kv.Value}\"");
            }
            File.WriteAllLines(dlg.FileName, lines);
            MessageBox.Show($"已导出 {_aliasMap.Count} 条别名记录。", "导出完成", 
                MessageBoxButton.OK, MessageBoxImage.Information);
        }

        private void BtnImport_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new OpenFileDialog { Filter = "CSV 文件|*.csv", Title = "导入别名映射" };
            if (dlg.ShowDialog() != true) return;

            int count = 0;
            foreach (var line in File.ReadLines(dlg.FileName).Skip(1))
            {
                var parts = ParseCsvLine(line);
                if (parts.Length >= 3 && Guid.TryParse(parts[0], out var guid))
                {
                    string alias = parts[2].Trim('"');
                    if (!string.IsNullOrWhiteSpace(alias))
                    {
                        _aliasMap[guid] = alias;
                        count++;
                    }
                }
            }
            RefreshTree();
            MessageBox.Show($"已导入 {count} 条别名记录。", "导入完成", 
                MessageBoxButton.OK, MessageBoxImage.Information);
        }

        // ==================== 辅助方法 ====================
        private string GetAlias(Guid guid) =>
            _aliasMap.ContainsKey(guid) ? _aliasMap[guid] : null;

        private void SaveAlias(Guid guid, string alias)
        {
            if (string.IsNullOrWhiteSpace(alias))
            {
                if (_aliasMap.ContainsKey(guid)) _aliasMap.Remove(guid);
            }
            else
            {
                _aliasMap[guid] = alias;
            }
        }

        private void RefreshNodeDisplay(Guid guid)
        {
            var node = FindNode(_rootNodes, guid);
            if (node != null) node.Alias = GetAlias(guid);
        }

        private AliasNode FindNode(List<<AliasNode> nodes, Guid guid)
        {
            foreach (var n in nodes)
            {
                if (n.Guid == guid) return n;
                var found = FindNode(n.Children, guid);
                if (found != null) return found;
            }
            return null;
        }

        private void ClearAllEditing(List<<AliasNode> nodes)
        {
            foreach (var n in nodes)
            {
                n.IsEditing = false;
                ClearAllEditing(n.Children);
            }
        }

        private static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                if (child is T t) return t;
                var result = FindVisualChild<T>(child);
                if (result != null) return result;
            }
            return null;
        }

        private static string[] ParseCsvLine(string line)
        {
            var result = new List<string>();
            bool inQuotes = false;
            var sb = new System.Text.StringBuilder();
            foreach (char c in line)
            {
                if (c == '"')
                {
                    inQuotes = !inQuotes;
                }
                else if (c == ',' && !inQuotes)
                {
                    result.Add(sb.ToString());
                    sb.Clear();
                }
                else
                {
                    sb.Append(c);
                }
            }
            result.Add(sb.ToString());
            return result.ToArray();
        }
    }
}

6. AliasGenerator.cs（批量自动生成别名）

using Autodesk.Navisworks.Api;
using System;
using System.Collections.Generic;

namespace AliasTree
{
    public class AliasGenerator
    {
        private Dictionary<<Guid, string> _result = new Dictionary<<Guid, string>();
        private HashSet<string> _usedNames = new HashSet<string>();

        public Dictionary<<Guid, string> Generate(ModelItem root, string separator = "/")
        {
            _result.Clear();
            _usedNames.Clear();
            if (root != null)
                Traverse(root, "", separator, 0);
            return _result;
        }

        private void Traverse(ModelItem item, string parentPath, string sep, int depth)
        {
            string rawName = item.DisplayName?.Trim() ?? "未命名";

            // 一级节点保持原名；二级开始加父前缀
            string alias = depth == 0
                ? rawName
                : (string.IsNullOrEmpty(parentPath) ? rawName : $"{parentPath}{sep}{rawName}");

            string uniqueAlias = MakeUnique(alias);
            _result[item.InstanceGuid] = uniqueAlias;

            // 下一级前缀：最多保留最近一级父名，避免路径无限膨胀
            string nextPrefix = depth < 1 ? uniqueAlias : rawName;

            foreach (var child in item.Children)
                Traverse(child, nextPrefix, sep, depth + 1);
        }

        private string MakeUnique(string name)
        {
            if (!_usedNames.Contains(name))
            {
                _usedNames.Add(name);
                return name;
            }

            int idx = 1;
            string candidate;
            do
            {
                candidate = $"{name}_{idx:D3}";
                idx++;
            } while (_usedNames.Contains(candidate));

            _usedNames.Add(candidate);
            return candidate;
        }
    }
}

编译与部署说明

| 项目         | 内容                                                                                                                                 |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **项目类型**   | Visual Studio → C# → 类库(.NET Framework)                                                                                            |
| **目标框架**   | .NET Framework 4.8（与 Navisworks 版本匹配）                                                                                              |
| **引用 DLL** | `Autodesk.Navisworks.Api.dll`<br>`Autodesk.Navisworks.Automation.dll`<br>位置通常在：`C:\Program Files\Autodesk\Navisworks Manage 2024\` |
| **输出路径**   | 编译后，将生成的 DLL 与 XAML/BAML 一起放入：<br>`%APPDATA%\Autodesk Navisworks Manage 2024\Plugins\AliasTree\`                                   |
| **启动**     | 重启 Navisworks，在 **View → Docking Windows** 中找到 **别名导航树**                                                                           |

使用流程（假设一个"八个楼层"的模型节点）
打开插件面板，dock 到内置 Selection Tree 旁边。
在内置树或 3D 视图中点选一个名叫"楼层"的节点。
别名树自动高亮该节点，顶部工具栏显示原名。
任选一种方式打别名：
鼠标悬停别名树节点 → 点 ✎ 铅笔 → 就地输入"8F-办公层" → 回车。
看 3D 视图确认位置 → 在顶部输入框敲"8F-办公层" → 点 ✓ 保存。
右键节点 → 编辑别名。
如果八个子节点全叫"楼层"，可点 自动生成 按钮，一键生成 楼层/楼层_001 … 楼层/楼层_007，你再精修成 1F大堂、2F办公 等。
工作完成后 导出 CSV，下次打开 Navisworks 时 导入 CSV 即可恢复所有别名。