如何在VS Code树视图的上下文菜单中添加输入框?
在VS Code树视图扩展中实现上下文菜单触发的输入框
要实现类似官方文件管理器的上下文菜单输入效果,你不需要用全局的showInputBox,可以通过以下两种方案实现:
方案1:利用TreeItem的可编辑标签(推荐,和官方逻辑一致)
如果你的需求是修改树项的标签(比如重命名),直接使用VS Code内置的树项编辑功能即可,完全贴合官方文件管理器的交互:
步骤1:配置上下文菜单
在package.json中注册上下文菜单命令,关联你的树视图:
{ "contributes": { "views": { "your-view-container": [ { "id": "your-tree-view-id", "name": "自定义树视图" } ] }, "menus": { "view/item/context": [ { "command": "your-extension.edit-item-label", "when": "view == your-tree-view-id", "group": "inline" } ] }, "commands": [ { "command": "your-extension.edit-item-label", "title": "重命名" } ] } }
步骤2:实现可编辑逻辑
在树数据提供者中设置树项可编辑,并监听标签修改事件:
import * as vscode from 'vscode'; class CustomTreeItem extends vscode.TreeItem { constructor( public label: string, public collapsibleState: vscode.TreeItemCollapsibleState ) { super(label, collapsibleState); } } export class CustomTreeDataProvider implements vscode.TreeDataProvider<CustomTreeItem> { private _onDidChangeTreeData = new vscode.EventEmitter<CustomTreeItem | undefined>(); readonly onDidChangeTreeData = this._onDidChangeTreeData.event; resolveTreeItem(item: CustomTreeItem, element: vscode.TreeItem): vscode.TreeItem { // 开启标签可编辑 element.editable = true; return element; } constructor() { // 监听标签修改完成事件 vscode.window.onDidChangeTreeItemLabel(async (event) => { const targetItem = event.item as CustomTreeItem; const newLabel = event.newLabel; if (newLabel) { // 这里添加你的业务逻辑,比如保存到数据源 targetItem.label = newLabel; // 更新树视图 this._onDidChangeTreeData.fire(targetItem); } }); } // 实现其他TreeDataProvider方法(getChildren、getTreeItem等) }
步骤3:绑定命令触发编辑
注册命令,触发树项的编辑状态:
vscode.commands.registerCommand('your-extension.edit-item-label', (item: CustomTreeItem) => { // 触发树项编辑 vscode.window.showTreeItemPicker(item).then(picker => { if (picker) { // 自动激活编辑状态 const treeView = vscode.window.createTreeView('your-tree-view-id', { treeDataProvider: new CustomTreeDataProvider() }); treeView.reveal(item, { select: true, focus: true }); // 触发编辑(VS Code会自动弹出输入框在树项位置) } }); });
方案2:自定义Webview输入面板(复杂UI场景)
如果需要更复杂的输入UI(比如多字段、自定义验证),可以创建嵌入侧边栏的Webview面板:
步骤1:注册命令和菜单(同方案1)
步骤2:实现Webview输入框
import * as vscode from 'vscode'; let inputPanel: vscode.WebviewPanel | undefined; export function activate(context: vscode.ExtensionContext) { const disposable = vscode.commands.registerCommand('your-extension.show-custom-input', (selectedItem: CustomTreeItem) => { // 复用已有面板或创建新面板 if (inputPanel) { inputPanel.reveal(vscode.ViewColumn.Beside); } else { inputPanel = vscode.window.createWebviewPanel( 'customInputPanel', '自定义输入', vscode.ViewColumn.Beside, { enableScripts: true, retainContextWhenHidden: true } ); // 渲染输入UI inputPanel.webview.html = ` <!DOCTYPE html> <html> <body style="padding: 10px;"> <label>输入内容:</label> <input type="text" id="inputValue" value="${selectedItem.label}" style="width: 100%; margin: 8px 0;" /> <button onclick="submit()" style="padding: 6px 12px;">确认</button> <script> const vscode = acquireVsCodeApi(); function submit() { const value = document.getElementById('inputValue').value.trim(); if (value) { vscode.postMessage({ type: 'submit', value, itemId: '${selectedItem.label}' }); } } </script> </body> </html> `; // 监听输入提交 inputPanel.webview.onDidReceiveMessage(msg => { if (msg.type === 'submit') { // 处理业务逻辑,比如更新树项 selectedItem.label = msg.value; // 通知树视图更新 customTreeDataProvider._onDidChangeTreeData.fire(selectedItem); // 关闭面板 inputPanel?.dispose(); inputPanel = undefined; } }); // 面板清理 inputPanel.onDidDispose(() => { inputPanel = undefined; }, null, context.subscriptions); } }); context.subscriptions.push(disposable); }
内容的提问来源于stack exchange,提问作者Soham Deogaonkar
相关产品推荐
相关产品推荐

