【问题标题】:VS Code - Updating Icons in TreeView in Custom ViewsContainerVS Code - 在自定义 ViewsContainer 中更新 TreeView 中的图标
【发布时间】:2019-04-05 02:53:59
【问题描述】:

所以自从这篇文章以来我取得了一些进展: Duplicate TreeView Schema is VS Code Extension

我已经将代码上传到了这个 repo:

https://github.com/trebleCode/dxdevcheck.git

我可以将静态 JSON 文件的内容放入我想要在我的自定义 viewsContainers 设置中的视图中。我的想法是激活该视图,根据带有未定义 iconPath 值的 JSON 内容将项目放入视图中,这样当我点击刷新按钮时,一些函数会运行并检查这些项目是否被视为“已配置”,如果是的话,用一个指示已配置或未配置的图标更新它们。

我现在的问题是,当我尝试使用一组具有值的新对象再次返回视图时,为什么我的 TreeDataViewProvider 上存在的 refresh() 方法不会更新这些图标到项目中的 .svg 文件。

只需克隆 repo,在克隆目录中运行 npm i,点击 F5 即可运行。

左侧面板上会出现一个闪电图标,点击后会加载一个新菜单,标有“验证”。下面将是四个可扩展/可折叠的项目,每个项目有两个孩子。当鼠标悬停在该菜单的右上角时,会出现一个圆形图标,上面会显示“验证这些东西!”。单击时,这将在右下角放置一个 ShowInformationMessage 模式。

这是 validateMenu.ts 中 ValidateMenuProvider 类中的 refresh() 方法。我已经在该部分中注释掉了我尝试过的代码,但无法理解它为什么会这样。

我想我正在尝试在我的扩展程序中的错误位置实现图标更新,因此任何指针表示赞赏。

我的班级:

import * as vscode from "vscode";
import * as validateMenuItems from "./validateMenu.json";
import * as path from "path";
import * as customUtils from "./customUtils";

export class ValidateMenuProvider implements vscode.TreeDataProvider<ValidateMenu> {
    private _onDidChangeTreeData: vscode.EventEmitter<ValidateMenu | undefined> = new vscode.EventEmitter<ValidateMenu | undefined>();
    readonly onDidChangeTreeData: vscode.Event<ValidateMenu | undefined> = this._onDidChangeTreeData.event;

    constructor() {}

    refresh() {
        // Why does this not work to update icons?
        vscode.window.showInformationMessage('Refresh button clicked!');
        return this.getValidateMenu(true);
        //
    }

    getTreeItem(element?: ValidateMenu): vscode.TreeItem {
        return element;
    }

    getChildren(element?: any, withIcons?: boolean): ValidateMenu[] {
        if(element) {
            return element.children;
        }
        else {
            return this.getValidateMenu();
        }
    }

    getValidateMenu(withIcons?: boolean): ValidateMenu[] {
        const toChild = (label: string, icon?: any): ValidateMenu => { return new ValidateMenu(label,vscode.TreeItemCollapsibleState.None);};

        function getMenusFromParent(target: any) {
            let childrenArray: any = [];

            for(let i in target) {
                let currentChild: string = target[i].name;
                let currentConvertedChild = toChild(currentChild);

                if(withIcons === true) {
                    let configCheck = currentConvertedChild.isConfigured(target[i].name);

                    if(configCheck === true) {
                        currentConvertedChild.setConfiguredIcon();
                    }
                    else if(configCheck === false) {
                        currentConvertedChild.setErrorIcon();
                    }
                }
                childrenArray.push(currentConvertedChild);
            }

            return childrenArray;
        }

        function createMenu(label: string, target: any) {
            let childData = getMenusFromParent(target);
            return new ValidateMenu(label, vscode.TreeItemCollapsibleState.Expanded, childData);
        }

        let headings = Object(validateMenuItems.children);
        let child1 = headings['child1'];
        let child2 = headings['child2'];
        let child3 = headings['child3'];
        let child4 = headings['child4'];

        let menus: any = [];

        menus.push(createMenu('child1', child1));
        menus.push(createMenu('child2', child2));
        menus.push(createMenu('child3', child3));
        menus.push(createMenu('child4', child4));

        return menus;
    }
}


export class ValidateMenu extends vscode.TreeItem {
    constructor(
        public readonly label: string,
        public readonly collapsibleState: vscode.TreeItemCollapsibleState,
        public children?: ValidateMenu[],
        public readonly command?: vscode.Command,
        public iconPath?: { light: string, dark: string }
    ) {
        super(label,collapsibleState);
    }

    setConfiguredIcon(): void {
        let newLightIcon: any;
        let newDarkIcon: any;

        newLightIcon = path.join(__filename, '..', '..', 'resources', 'light', 'checkmark.svg');
        newDarkIcon = path.join(__filename, '..', '..', 'resources', 'dark', 'checkmark2.svg');

        if(this.iconPath === undefined) {
            this.iconPath = {light: newLightIcon, dark: newDarkIcon};
        }
        else {
            this.iconPath = {light: newLightIcon, dark: newDarkIcon};
        }
    }

    setErrorIcon(): void {
        let newLightIcon: any;
        let newDarkIcon: any;

        newLightIcon = path.join(__filename, '..', '..', 'resources', 'light', 'confused2.svg');
        newDarkIcon = path.join(__filename, '..', '..', 'resources', 'dark', 'confused.svg');

        if(this.iconPath === undefined) {
            this.iconPath = {light: newLightIcon, dark: newDarkIcon};
        }
        else {
            this.iconPath = {light: newLightIcon, dark: newDarkIcon};
        }
    }

    isConfigured(name: string): boolean {
        if(customUtils.checkIsConfigured(name) === true) {
            return true;
        }
        else {
            return false;
        }
    }
}

我的静态 JSON 文件:

{
    "name": "root",
    "children": {
        "child1": [
            {"id": "id1", "name": "child1name1"},
            {"id": "id2", "name": "child2name2"}
        ],
        "child2": [
            {"id": "id1", "name": "child2name1"},
            {"id": "id2", "name": "child2name2"}
        ],
        "child3": [
            {"id": "id1", "name": "child3name1"},
            {"id": "id2", "name": "child3name2"}
        ],
        "child4": [
            {"id": "id1", "name": "child4name1"},
            {"id": "id2", "name": "child5name2"}
        ]
    }
}

以及我从一些导入的函数 (customUtils.ts) 中调用的一些辅助实用程序:

export function checkIsConfigured(name: string): boolean {
     let isConfigured: boolean;
    switch (name) {
        case 'child1':
                isConfigured = checkChild1();
            break;
        case 'child2':
             isConfigured = checkChild2();
            break;
        case 'child1':
             isConfigured = checkChild3();
            break;
        case 'child1':
             isConfigured = checkChild4();
            break;
    }
    return isConfigured;
}

export function checkChild1() {
    return true;
}

export function checkChild2() {
    return false;
}

export function checkChild3() {
    return true;
}

export function checkChild4() {
    return false;
}

最后是package.json:

{
    "name": "myview",
    "displayName": "MYVIEW",
    "description": "checks dev things",
    "version": "0.0.2",
    "publisher": "someperson",
    "engines": {
        "vscode": "^1.28.0"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [
        "onView:validateMenu"
    ],
    "main": "./out/extension.js",
    "contributes": {
        "viewsContainers": {
            "activitybar": [
                {
                    "id": "myview",
                    "title": "My Custom View Container",
                    "icon": "resources/bolt.svg"
                }
            ]
        },
        "views": {
            "myview": [
                {
                    "id": "validateMenu",
                    "name": "Validate"
                }
            ]
        },
        "commands": [
            {
                "command": "validateMenu.refreshList",
                "title": "Validate the things!",
                "icon": "resources/spinner.svg"
            }
        ],
        "menus": {
            "view/title": [
                {
                    "command": "validateMenu.refreshList",
                    "when": "view == validateMenu",
                    "group": "navigation"
                }
            ]
        }
    },
    "scripts": {
        "vscode:prepublish": "npm run compile",
        "compile": "tsc -p ./",
        "watch": "tsc -watch -p ./",
        "postinstall": "node ./node_modules/vscode/bin/install",
        "test": "npm run compile && node ./node_modules/vscode/bin/test"
    },
    "devDependencies": {
        "@types/mocha": "^2.2.42",
        "@types/node": "^10.12.21",
        "tslint": "^5.12.1",
        "typescript": "^3.3.1",
        "vscode": "^1.1.28"
    },
    "dependencies": {}
}

【问题讨论】:

  • “确保重现问题所需的所有信息都包含在问题本身中” - stackoverflow.com/help/mcve。更何况,GitHub 链接似乎都不起作用?
  • @Gama11 我更改了链接并更新了详细信息。够了吗?
  • 该链接仍然对我不起作用 (404)。而且您的问题中仍然没有包含任何代码。
  • @Gama11 链接为私有,已更新,相关代码已发布
  • 我是否只需要在我的getValidateMenu 方法上使用一个事件发射器接口来发出onDidChangeTreeData 可以理解的事件?

标签: typescript visual-studio-code vscode-extensions


【解决方案1】:

要更改图标,需要在package.json 中设置图标路径,然后设置context 值,该值将在调用refresh 方法或创建@987654323 时进行评估@ 和iconPath 然后调用刷新方法。

前者的例子:

  "menus": {
    "view/title": [{
      "command": "nodeDependencies.refreshEntry",
      "when": "view == nodeDependencies && shouldRefresh",
      "group": "navigation"
    }]
  }
vscode.commands.executeCommand('setContext', 'shouldRefresh', true);

【讨论】:

  • 谢谢@RobertBrisita
  • 很高兴能帮上忙!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-20
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2022-12-29
相关资源
最近更新 更多