Как сделать виртуальный узел с использованием MPF? - PullRequest
1 голос
/ 01 ноября 2010

Я создаю новый тип проекта с использованием MPF.

Я хочу создать тип узла, в котором поддержка для этого узла фактически нигде не существует. Чтобы было проще, я просто хочу создавать подписи на лету.

Я создал новый подкласс узла из HierarchyNode, потому что у него в конечном итоге будут дочерние элементы. Я создал подкласс FolderNode, чтобы определить, какие папки будут иметь эти виртуальные узлы как дочерние. Я использую Get / SetMetadata, чтобы сделать это, и он отлично работает. Я переопределил GetProperty в MyFolderNode, чтобы, если тип папки был «нормальной», она просто направлялась на базу. В противном случае он возвращает VirtualNode для FirstChild. Виртуальные узлы создают своего следующего брата и устанавливают для него NextSibling. TL; DR: код следует.

Моя проблема в том, что это не работает. В частности, когда я нажимаю на значок «Развернуть эту папку», он становится синим (так что щелчок регистрируется), но остается синим, а узел не расширяется. Отладка показывает, что попытка развернуть папку приводит к тому, что GetProperty запрашивает FirstChild и возвращает идентификатор первого дочернего элемента. После этого VirtualNode запрашивается дважды, чтобы узнать, расширяем ли он. Затем он запрашивается для подписи. Затем значок. Тогда ничего.

Вот код для моего подкласса FolderNode:

public class AndroidFolderNode : FolderNode
{
    public enum FolderType
    {
        Normal,
        JavaSource
    }

    public string[] VirtualNodes = new[]
                                    {
                                        "Virtual Node One",
                                        "Virtual Node Two",
                                        "Virtual Node Three"
                                    };

    private FolderType mFolderType;
    public FolderType Type
    {
        get
        {
            return mFolderType;
        }
        set
        {
            if (mFolderType != value)
            {
                mFolderType = value;
                OnInvalidateItems(this);
            }
        }
    }

    private HierarchyNode mVirtualChild;

    public AndroidFolderNode(ProjectNode root, string relativePath, ProjectElement element)
        : base(root, relativePath, element)
    {
        var t = element.GetMetadata("Type");
        if (string.IsNullOrWhiteSpace(t))
        {
            Type = FolderType.Normal;
        }
        else
        {
            FolderType tempType;
            if (Enum.TryParse(t, true, out tempType))
            {
                Type = tempType;
            }
        }
    }

    protected override NodeProperties CreatePropertiesObject()
    {
        return new AndroidFolderNodeProperties(this);
    }


    public override object GetProperty(int propId)
    {
        object result = null;
        switch ((__VSHPROPID) propId)
        {
            case __VSHPROPID.VSHPROPID_FirstChild:
                goto case __VSHPROPID.VSHPROPID_FirstVisibleChild;

            case __VSHPROPID.VSHPROPID_FirstVisibleChild:
                if (Type == FolderType.Normal)
                {
                    result = (int)((this.FirstChild != null) ? this.FirstChild.ID : VSConstants.VSITEMID_NIL);
                }
                else
                {
                    if (mVirtualChild == null)
                    {
                        mVirtualChild = new VirtualFolderNode(this, 0);
                    }
                    result = mVirtualChild.ID;
                }
                break;
            default:
                result = base.GetProperty(propId);
                break;
        }
        return result;
    }
}

Вот код моего виртуального узла:

class VirtualFolderNode : HierarchyNode
{
    private static Guid _guid = new Guid("DD264E51-2E66-4BCC-A8A6-DE3BDE890DED");

    private int mIdx;
    private AndroidFolderNode mParent;
    private VirtualFolderNode mSibling;

    public VirtualFolderNode(AndroidFolderNode parent, int idx)
        : base(parent.ProjectMgr)
    {
        mParent = parent;
        mIdx = idx;
        Parent = parent;

        if (idx < parent.VirtualNodes.Length)
        {
            mSibling = new VirtualFolderNode(parent, idx + 1);
            NextSibling = mSibling;
        }
    }

    public override string Url
    {
        get { return Parent.Url + "\\VNode" + mIdx; }
    }

    public override string Caption
    {
        get { return mParent.VirtualNodes[mIdx]; }
    }

    public override Guid ItemTypeGuid
    {
        get { return _guid; }
    }
}

1 Ответ

1 голос
/ 01 ноября 2010

Понял! (Примечание: раньше мне никогда не приходилось отвечать на свой вопрос.)

Проблема, похоже, в том, что HierarchyNode.GetIconHandle (bool open) просто возвращает ноль. Переопределение GetIconHandle в VirtualNode позволяет отображать его должным образом. Поэтому я добавил это в VirtualNode и bada bing, bada boom:

    public override object GetIconHandle(bool open)
    {
        return ProjectMgr.ImageHandler.GetIconHandle(open ? (int)ProjectNode.ImageName.OpenFolder : (int)ProjectNode.ImageName.Folder);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...