跳到主要内容

定位节点、选中、复选框和拖拽怎么接?

结论​

定位用 TreeView.reveal,前提是提供器实现了 getParent。选中读 TreeView.selection 并监听 onDidChangeSelection。复选框开在 TreeItem.checkboxState 上。拖拽要实现 TreeDragAndDropController。

展开​

createTreeView 才拿得到 TreeView 句柄。registerTreeDataProvider 适合不需要这些交互的简单树。

定位:

await tree.reveal(node, { select: true, focus: true, expand: true });

编辑器从目标节点顺着 getParent 走到根,把路径上的节点展开,所以父链必须完整。节点还没被加载时,getParent 仍然要能答上来,不能只在已经展开过的对象里找。

选中:

  • tree.selection 是当前数组,多选时不止一个
  • 命令如果从右键来,处理函数会收到点中的那个节点;和「当前 selection」可能不是同一个概念,要以命令参数为准

复选框:

item.checkboxState = vscode.TreeItemCheckboxState.Unchecked;

监听 tree.onDidChangeCheckboxState,里面改你的模型,再按需要刷新。不要只改 TreeItem 不改数据源,下次 getChildren 会把勾选还原。

拖拽:

  • dragMimeTypes 声明你拖出的类型
  • dropMimeTypes 声明你接收的类型
  • handleDrag 往 DataTransfer 里写数据
  • handleDrop 读出来,改模型,再刷新

接收编辑器外部文件时,MIME 要用编辑器约定的资源列表类型,从中取出 URI。

容易讲错的点​

  • 没有 getParent 时,reveal 只能对已经展开路径上的节点勉强工作,深层节点会失败。
  • 复选框状态不是上下文键。菜单要跟着勾选变化时,还要另外 setContext 或换 contextValue。
  • 拖拽控制器和数据提供器一起交给 createTreeView 的选项。只实现了方法但没传进去,不会生效。