You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:45:23