UCMS Navigator
UCMS Navigator 是面向 UCMS 分层项目和 WPF/MVVM 工作流的 VS Code 导航与工作台扩展,重点解决以下问题:
- 在 Entity、Model、Service、Controller、View、ViewModel 之间快速跳转。
- 在 View 与 ViewModel 之间做“同名/同变体”快速切换。
- 在多页面实体中,快速切换 Add/Edit/Detail/List/Page 等不同 UI 文件。
- 兼容主客户端
UCMS.WPF 与附加客户端目录,例如 Client/Apps/UCMS.Wpf.Dashboard。
- 为 C# 提供「转到定义 / 查找所有引用」的名称级兜底(官方语言服务没加载时也能跳)。
- 在底部状态栏集中提供“导航 | 工作台 | 调试”工作流入口。
- 用分组菜单执行 Cloosom、UCMS 的常用任务,而不再依赖一长串状态栏按钮。
- 默认不采集遥测,不发起外部网络请求。
- 通过工作区配置文件定义插件内的发布与调试菜单,避免每次都改扩展源码。
核心能力
1. 关联文件总览
按 Alt+G 可打开当前实体的全部关联文件列表,覆盖以下层:
- Entity
- Model
- Repository / IRepository
- Service / IService
- ApiService
- Controller
- View
- ViewModel
- Helpers
2. 匹配 View/ViewModel 快速切换
当当前文件是 View 或 ViewModel 时:
- 按
Alt+Shift+V 可直接切到最可能匹配的对端文件。
- 扩展会优先匹配同名变体,例如:
MaterialAddView.xaml → MaterialAddViewModel.cs
MaterialEditViewModel.cs → MaterialEditView.xaml
OeeHistoryViewModel.cs → OeeHistoryView.xaml
EnergyEnvironmentPage.xaml → EnergyEnvironmentViewModel.cs
3. View/ViewModel 选择器
按 Alt+Shift+G 可只查看当前实体的 View 与 ViewModel 文件,适合在多个页面变体之间切换。
4. CodeLens 与导航状态栏
- View / ViewModel 文件顶部会出现“匹配 View/ViewModel” CodeLens。
- 底部状态栏在普通文件中显示实体和当前层。
- 当当前文件是 View 或 ViewModel 时,导航状态栏会直接变成“切换对端文件”。
5. C#/XAML/前端结构面板
扩展现在会在 VS Code 左侧活动栏提供一个独立的 结构 按钮,点开后就是 UCMS 结构 面板,用于查看当前 .cs、.xaml、.ts、.tsx、.js、.jsx、.html 或 .vue 文件中的结构。
在 C# 文件中会显示:
- 类、记录类型、接口、结构体、记录结构体、枚举、委托
- 字段、属性、索引器、事件、构造函数
- 公共 / 受保护 / internal / 私有方法,以及运算符重载
- 可选的
#region 分组,可通过筛选或标题栏按钮显示 / 隐藏
在 XAML 文件中会显示:
- XAML 元素层级
x:Name / Name / x:Key 命名元素
- 常见
Command 和 Binding 信息
Command / Binding 子节点可跳转到关联 ViewModel 中匹配的命令方法或属性
- 启用关联文件时,对应 ViewModel 的 C# 成员结构
在前端文件中会显示:
- TS / JS / TSX / JSX 的语言服务符号,例如类、函数、方法、属性、变量、导出成员
- HTML 元素层级,以及
id / name / class 等命名提示
- Vue 单文件组件的模板层级、
ref / v-model / @click / :prop 等常见指令摘要
- Vue
<script> 区域在语言服务可解析时返回的脚本符号
同时支持:
- 整个文件 / 当前类型 / 当前成员 三种焦点范围;聚焦时仍保留当前文件里的所有类型节点
- 当前光标所在结构路径自动展开并标记
- 鼠标悬浮类、方法、属性等节点时,显示 XML 注释说明、参数和返回值摘要
- 一键套用三种结构预设:显示所有成员、显示对外 API、显示对内 API
- 一键切到“对外 API(当前类型)”视图,只看 public / protected 内容;再次点击会恢复到全部成员
- 顶部一键聚焦到当前光标位置,并可开启 / 关闭自动定位
- 顶部一键显示 / 隐藏
#region 分组;隐藏时只移除分组外壳,成员仍保留在树中
- 顶部展开 / 折叠按钮会按当前展开状态自动切换图标
- 标题栏和状态栏都能快速打开最近结构文件历史,按打开时间倒序展示,最多保留 10 条并自动覆盖最旧记录
- 标题栏描述会直接显示当前的定位、关联、展开模式和焦点范围状态
- 按代码位置排序
- 按名字排序
- 按类型排序
- 按结构类型筛选显示项
- 按可见性筛选显示项
- 按关联类型筛选关联文件
- 配置是否启用
#region 等 C# 内置切分规则
当启用“关联文件”时,结构面板还会尝试同时展示:
- 基类文件中的结构
- 接口文件中的结构
- partial 同名类型所在文件中的结构;扩展会优先按同名文件前缀做轻量文本解析,并会识别源码生成器输出的分部类
- XAML View 对应 ViewModel 文件中的成员结构
点击面板中的任意符号,会直接跳到对应定义位置。XAML 普通元素仍跳回 XAML 标签本身;Binding: / Command: 子节点只在关联 ViewModel 中找到明确匹配时才跳转,避免跳到不对应的成员。关联文件候选会按规范化文件路径去重;源码生成器生成的 partial 会按生成文本指纹去重,减少多目标框架或 WPF 临时编译输出重复出现。
手动点击 聚焦到当前位置 时,结构树会直接选中并滚动到当前光标所在符号或 XAML 元素,而不是只刷新文件列表。展开 / 折叠也由扩展自己维护状态,避免在第一次刷新后看起来无效。对外 API 是双态按钮,开启后只看当前类型的 public / protected 内容,再点会恢复到全部成员;关联文件显示是独立开关,不会被成员预设强制改掉。
如果你没有看到这个面板:
- 先确认左侧活动栏里已经出现
结构 图标
- 或者在命令面板执行
UCMS: 打开结构面板
- 打开任意
.cs、.xaml、.ts、.js、.html 或 .vue 文件后,结构树会按当前文件刷新
6. C# 转到定义 / 查找引用(名称级兜底)
在 .cs 文件里「转到定义 (Go to Definition, F12)」和「查找所有引用 (Find All References, Shift+F12)」现在多了一层名称级兜底:扩展会扫描全仓 .cs 建立声明索引,即使官方 C# 语言服务(Roslyn / C# Dev Kit)没加载、.slnx 加载不全、或大解决方案还在后台初始化,你也能跳到类型 / 方法 / 属性 / 字段的声明,或列出它们的引用。
- 真·语义级跳转(重载 / 泛型 / 继承消歧)仍由官方 C# 语言服务提供;VS Code 会把两者结果聚合去重,语言服务正常时不冲突。
- 精度边界:转到定义遇同名声明会一并列出(在 peek 里选);查找引用是
\bName\b 文本匹配,等价于「按标识符的智能 grep」,可能含少量同名噪声。
- 索引在扩展激活后延后约 4 秒后台构建(让路给 C# 语言服务先加载),并随文件增删改增量更新。
- 若官方语言服务已完全正常、不想要这层兜底,把设置
ucms.navigation.enableSymbolIndex 关掉即可。
根治提示:若官方跳转本身就跳不动(常见于只有 .slnx、无传统 .sln 时 C# Dev Kit 加载不全),根本办法是让语言服务正确加载整个解决方案 —— 仓库已生成传统 src/UCMS.Business.sln 并把 .vscode/settings.json 的 dotnet.defaultSolution 指向它,重载窗口或执行 .NET: Restart Language Server 后原生语义跳转应恢复。
7. 工作台、发布与调试状态栏
- 导航条目右侧会显示
| 工作台 | 结构历史 | 发布 | 调试。
- “工作台”会弹出分组菜单,集中执行以下任务:
- Cloosom 版本同步 / 发布包
- UCMS 升级包 / 编译全部 / 发布 / 数据库迁移
- 完整任务列表 / 打开工作台配置
- “发布”会打开插件内的发布菜单,菜单项由工作区配置文件提供。
- “调试”会打开插件内的调试菜单;推荐直接接入 VS Code 原生“选择调试配置”,把
launch.json 里现成的 net6 / net10、单项和组合入口直接透出给用户。
task 动作除了引用已有 taskLabel,也支持直接在配置文件里写 taskCommand + taskArgs,适合做可配置的跨脚本编排任务。
- 可通过
Alt+Shift+U 直接打开工作台菜单。
命令列表
| 命令 |
快捷键 |
说明 |
UCMS: 跳转到关联文件 |
Alt+G |
打开实体关联文件列表 |
UCMS: 切换匹配的 View/ViewModel |
Alt+Shift+V |
直接跳转到最可能匹配的对端文件 |
UCMS: 选择 View/ViewModel |
Alt+Shift+G |
仅查看当前实体的 View 与 ViewModel |
UCMS: 打开工作台菜单 |
Alt+Shift+U |
打开分组任务菜单 |
UCMS: 打开发布菜单 |
- |
打开插件内发布菜单 |
UCMS: 打开调试菜单 |
- |
打开插件内调试菜单 |
UCMS: 打开工作台配置文件 |
- |
打开或创建 .vscode/ucms-navigator.workbench.json |
UCMS: 显示实体概览 |
- |
Markdown 方式展示实体全景 |
UCMS: 打开结构面板 |
- |
打开左侧结构按钮对应的面板 |
UCMS: 聚焦到当前位置 |
- |
将结构树定位到编辑器当前光标所在结构节点 |
UCMS: 一键显示对外 API |
- |
切到当前类型的 public / protected 视图 |
UCMS: 开启自动定位当前符号 |
- |
开启编辑器与结构树的自动定位联动 |
UCMS: 关闭自动定位当前符号 |
- |
关闭编辑器与结构树的自动定位联动 |
UCMS: 显示 Region 分组 |
- |
显示 C# #region 分组节点 |
UCMS: 隐藏 Region 分组 |
- |
隐藏 C# #region 分组节点并保留其成员 |
UCMS: 展开/折叠全部结构 |
- |
在展开当前结构树所有层级和折叠结构树之间切换 |
UCMS: 打开结构文件历史 |
- |
按时间倒序打开最近 10 个结构文件 |
UCMS: 刷新结构 |
- |
刷新当前支持文件的结构面板 |
UCMS: 设置结构排序 |
- |
在位置 / 名字 / 类型之间切换排序 |
UCMS: 设置结构焦点范围 |
- |
在整个文件 / 当前类型或元素 / 当前成员或元素路径间切换 |
UCMS: 应用结构预设 |
- |
一键切到显示所有成员、显示对外 API、显示对内 API |
UCMS: 配置结构筛选 |
- |
配置显示项、访问级别、关联类型和 C# 切分规则 |
UCMS: 切换结构关联文件 |
- |
一键开关基类 / 接口 / partial / ViewModel 结构 |
UCMS: 跳转到 Entity |
- |
直达 Entity |
UCMS: 跳转到 Model |
- |
直达 Model |
UCMS: 跳转到 Service |
- |
直达 Service |
UCMS: 跳转到 Controller |
- |
直达 Controller |
UCMS: 跳转到 Repository |
- |
直达 Repository |
UCMS: 跳转到 View |
- |
直达 View |
UCMS: 跳转到 ViewModel |
- |
直达 ViewModel |
UCMS: 跳转到 ApiService |
- |
直达 ApiService |
识别规则
扩展根据文件名和路径自动识别实体与层,例如:
| 文件名 |
识别结果 |
MaterialEntity.cs |
Entity: Material |
MaterialModel.cs |
Model: Material |
MaterialEditView.xaml |
View: Material |
MaterialEditViewModel.cs |
ViewModel: Material |
EnergyEnvironmentPage.xaml |
View: EnergyEnvironment |
EnergyEnvironmentViewModel.cs |
ViewModel: EnergyEnvironment |
当前已覆盖的 UI 项目目录包括:
UCMS.WPF
Client/Apps/UCMS.Wpf.*
结构面板设置
可通过 VS Code 设置搜索以下项:
ucms.structure.autoRevealCurrentSymbol
ucms.structure.scopeMode
ucms.structure.sortBy
ucms.structure.visibleKinds
ucms.structure.visibleVisibilities
ucms.structure.includeRelatedFiles
ucms.structure.visibleRelationKinds
ucms.structure.enabledCsharpRules
工作台配置文件
扩展会自动读取每个工作区根目录下的 .vscode/ucms-navigator.workbench.json 来决定插件内显示哪些“发布/调试/工作台”菜单项。
这意味着后续如果你要:
- 增加一个新的发布目标
- 增加一个新的调试入口
- 改菜单标题、描述、顺序
- 切换某个工作区显示哪些插件菜单
只需要改配置文件,不需要再改扩展源码。
配置文件结构
{
"sections": [
{
"id": "publish",
"title": "发布",
"actions": [
{
"label": "License Generator 发布 [net10]",
"description": "Cloosom.Licensing.Generator",
"detail": "发布授权生成器 WPF 工具",
"kind": "publish",
"project": "Cloosom.Licensing.Generator/Cloosom.Licensing.Generator.csproj",
"framework": "net10.0-windows",
"configuration": "Release",
"outputDir": "Cloosom.Licensing.Generator/bin/Publish/net10.0-windows",
"stopProcesses": ["Cloosom.Licensing.Generator"],
"properties": {
"EnableBuildObfuscation": "false",
"EnablePublishObfuscation": "true",
"GeneratePackageOnBuild": "false"
}
},
{
"label": "UCMS 全流程发布 [net10]",
"description": "UCMS",
"detail": "直接在配置文件里定义顺序发布命令",
"kind": "task",
"taskCommand": "powershell.exe",
"taskArgs": [
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"& \"${workspaceFolder}/Scripts/Build/publish.ps1\" -Profile small -Project backend -Framework net10 -SkipConfirmation; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; & \"${workspaceFolder}/Scripts/Build/publish.ps1\" -Profile small -Project wpf -Framework net10 -SkipConfirmation; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; & \"${workspaceFolder}/Scripts/Build/publish.ps1\" -Profile small -Project web -Framework net10 -SkipConfirmation; exit $LASTEXITCODE"
]
}
]
},
{
"id": "debug",
"title": "调试",
"actions": [
{
"label": "License Generator 调试 [net10]",
"description": "Cloosom.Licensing.Generator",
"detail": "构建并启动授权生成器 WPF 工具",
"kind": "debug",
"project": "Cloosom.Licensing.Generator/Cloosom.Licensing.Generator.csproj",
"framework": "net10.0-windows",
"configuration": "Debug",
"cwd": "Cloosom.Licensing.Generator",
"stopProcesses": ["Cloosom.Licensing.Generator"],
"properties": {
"EnableBuildObfuscation": "false",
"GeneratePackageOnBuild": "false"
}
}
]
}
]
}
支持的动作类型
separator:在同一个菜单 section 内插入可见分组线。
task:按任务标签运行已有 VS Code task;也支持直接在配置里定义 taskCommand + taskArgs。
command:执行 VS Code 命令。
launch:按名称直接启动现有 launch.json 配置或 compound。
publish:由插件直接构造并运行 dotnet publish。
debug:由插件先 dotnet build,成功后直接调用 vscode.debug.startDebugging。
publish / debug / launch 常用字段
workspaceFolder:目标工作区名或路径;省略时默认取配置文件所在工作区。
taskLabel:仅 task 使用,对应已有 tasks.json 任务名。
taskCommand / taskArgs:仅 task 使用,直接定义要执行的命令和参数,适合做可配置的串联脚本。
launchName:仅 launch 使用,对应 launch.json 中的配置或 compound 名称。
project:相对工作区的 .csproj 路径。
framework:例如 net10.0-windows。
configuration:例如 Debug 或 Release。
cwd:运行目录。
outputDir:仅 publish 使用,对应 PublishDir。
stopProcesses:发布或调试前要结束的进程名数组。
properties:附加的 MSBuild 属性。
args:仅 debug 使用,传给启动程序的参数。
program:仅 debug 使用,自定义启动 dll 路径;不填时按 bin/<Configuration>/<TFM>/<ProjectName>.dll 推导。
本地开发
cd tools/ucms-navigator
npm ci
npm run compile
npm run watch
npm run package
npm run package:vsix
安装 VSIX:
code --install-extension ucms-navigator-0.7.28.vsix
快速发布到 Marketplace
首次发布只需要做一次登录:
cd tools/ucms-navigator
npm run login:marketplace
登录成功后,后续发布直接执行:
cd tools/ucms-navigator
npm run publish:marketplace
如果你只想先生成安装包给内部测试,则继续使用:
npm run package:vsix
发布前提:
- Azure DevOps PAT 作用域至少包含
Marketplace (Manage)。
- PAT 的 Organization 需选择
All accessible organizations。
package.json 中的 publisher 必须与 Marketplace 中已创建的 Publisher ID 一致。
- VS Code Marketplace 发布不使用帐号密码登录,这里需要的是 PAT,而不是密码。
隐私与数据
- 不上传工作区代码、文件内容或项目元数据到任何外部服务。
- 不内置遥测、分析埋点或自动更新逻辑。
- 仅基于当前 VS Code 工作区中的文件名与目录结构做本地导航判断。
许可证
本扩展按 MIT License 分发,详见根目录 LICENSE。
打包与隐私控制
当前 VSIX 打包默认只包含以下文件:
dist/extension.js
images/icon.png
README.md
CHANGELOG.md
LICENSE
package.json
这意味着以下内容不会进入 VSIX:
src/**
node_modules/**
package-lock.json
- 调试目录和临时文件
- 任何工作区源码或本地用户路径
如果你后续准备发布到 Marketplace,建议在真正发布前执行一次 VSIX 内容检查,确保没有新增的敏感文件被打进包内。