Reputation: 1062
I'm playing with building a vscode extension, using the TreeDataProvider API. I have a list of things showing, each TreeItem a composed label string, all works fine.
What I am missing is a way of reacting to click events on any of the items. VSCode selects the item when you click on it, but I'd like to listen to that event, get the item in question etc... It's not obvious to me from the docs.
In general, customizing the TreeItem is severely lacking, e.g. being able to colorize the label or pass a more flexible UI component in instead of just a string... Maybe I'm missing something?
Upvotes: 6
Views: 3882
Reputation: 180805
Apparently added after the question and answer, there are these "TreeViewEvents":
onDidChangeSelection: Event<TreeViewSelectionChangeEvent<T>>
onDidChangeVisibility: Event<TreeViewVisibilityChangeEvent>
onDidCollapseElement: Event<TreeViewExpansionEvent<T>>
onDidExpandElement: Event<TreeViewExpansionEvent<T>>
from TreeView api
Using this sample code from one of my extensions:
const viewSelection = this.tabView.onDidChangeSelection(
debounce( async event => {
...
}, 1000, {isImmediate: true})
);
event.selection
will be an array of your extended TreeItems
that were selected.
Upvotes: 2
Reputation: 34138
VSCode selects the item when you click on it, but I'd like to listen to that event, get the item in question etc...
You can use TreeItem.command
to run some command when a tree item is selected, and then register a callback for that command. Here's a simple example that traces the label of a tree item to the console:
'use strict';
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
vscode.window.registerTreeDataProvider("exampleTreeView", new ExampleTreeProvider());
vscode.commands.registerCommand("exampleTreeView.selectNode", (item:vscode.TreeItem) => {
console.log(item.label);
});
}
export class ExampleTreeProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
getTreeItem(element: vscode.TreeItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
return element;
}
getChildren(element?: vscode.TreeItem): vscode.ProviderResult<vscode.TreeItem[]> {
if (element == null) {
var item = new vscode.TreeItem("Foo");
item.command = {
command: "exampleTreeView.selectNode",
title: "Select Node",
arguments: [item]
};
return [item];
}
return null;
}
}
"contributes": {
"views": {
"explorer": [
{
"id": "exampleTreeView",
"name": "Example Tree View"
}
]
}
},
The command
can be any arbitrary string, but I like to "scope" it by prefixing the view ID. It's important to pass the item itself via arguments
if you want to access any of its properties in the callback.
In general, customizing the TreeItem is severely lacking, e.g. being able to colorize the label or pass a more flexible UI component in instead of just a string...
That sounds like an accurate assessment, the API is a bit limiting in some ways. If you need more freedom, the recently introduced Webview API might be a good alternative. Note that that would mean implementing your own tree view from scratch using HTML/CSS/JS.
Upvotes: 12