Home > front end >  How to refresh vscode.TreeDataProvider based TreeView?
How to refresh vscode.TreeDataProvider based TreeView?

Time:05-23

the TreeView is initially populated and the TreeView instantiated. the 'refresh' button invokes the custom refresh function to gather updated data. This new information is stored in context.globalState()

The ctmInfrastructureProvider.refresh(); does not update the TreeView. I've added the event listener as well.

export class CtmInfrastructureProvider implements vscode.TreeDataProvider<number> {

    private _onDidChangeTreeData: vscode.EventEmitter<number | null> = new vscode.EventEmitter<number | null>();
    readonly onDidChangeTreeData: vscode.Event<number | null> = this._onDidChangeTreeData.event;
.
.
.
    constructor(private context: vscode.ExtensionContext) {
        let ctmInfrastructureCacheTmp: any = context.globalState.get('ctmInfrastructureCache');
        this.refresh();
    }
.
.
.
}

Here are my refresh functions:

let ctmInfrastructureRefreshEntry = vscode.commands.registerCommand(
        'ctm.infrastructure.refreshEntry',
        async () => {           
ctmInfrastructureDicsovery = discoverCtmInfrastructure();                     context.globalState.update('ctmInfrastructureCache',JSON.parse(ctmInfrastructureDicsovery));
ctmInfrastructureProvider.refresh();
        }
    );
    context.subscriptions.push(ctmInfrastructureRefreshEntry);

The TreeDataProvider refresh()

    refresh(offset?: number): void {
            this.parseTree();
    }
    private parseTree(): void {
        this.text = this.ctmInfrastructureCache;
        this.tree = json.parseTree(this.ctmInfrastructureCache);
    }

What am I missing?

CodePudding user response:

You have to trigger the change event yet:

    refresh(offset?: number): void {
            this.parseTree();
        this._onDidChangeTreeData.fire();
    }

Update

Actually, I use a slightly different approach than that from the tree demo:

import { TreeDataProvider, TreeItem, EventEmitter, TextDocument, ProviderResult, Event } from "vscode";
import { AntlrFacade } from "../backend/facade";

export class AntlrTreeDataProvider<T> implements TreeDataProvider<T> {
    protected currentFile: string | undefined;

    private changeEvent = new EventEmitter<void>();

    public constructor(protected backend: AntlrFacade) { }

    public get onDidChangeTreeData(): Event<void> {
        return this.changeEvent.event;
    }

    public refresh(document: TextDocument | undefined): void {
        if (document && document.languageId === "antlr" && document.uri.scheme === "file") {
            this.currentFile = document.fileName;
        } else {
            this.currentFile = undefined;
        }
        this.changeEvent.fire();
    }

    public getTreeItem(element: T): TreeItem {
        return element;
    }

    public getChildren(_element?: T): ProviderResult<T[]> {
        return undefined;
    }
}

Taken from my VS Code extension: https://github.com/mike-lischke/vscode-antlr4/blob/master/src/frontend/AntlrTreeDataProvider.ts. As you can see I use EventEmitter instead, which does not require a parameter for the fire() event.

CodePudding user response:

The refresh is working if the new data is being provided by the function. Example:

    refresh(offset?: number, context?: vscode.ExtensionContext): void {
        this.ctmInfrastructureCache = "some data";
        this.parseTree();
        if (offset) {
            this._onDidChangeTreeData.fire(offset);
        } else {
            this._onDidChangeTreeData.fire(undefined);
        }

    }
  • Related