Как программно обновлять/обновлять глифы в обозревателе решений?

Я создал пакет VSIX, который отображает статусы файлов в виде глифов в обозревателе решений в VS2010. Я реализовал базовый SccProvider (унаследованный от IVsSccProvider, IVsSccManager2, IVsSccGlyphs и других), включая метод GetSccGlyph. Поэтому, когда решение открывает пакет vsix, он успешно загружает начальные глифы для всего решения. Но я не могу найти способ обновить глиф конкретного (или всего) элемента решения. Соответствующий способ должен выглядеть

var rgsiGlyphs = new VsStateIcon[1];
var rgdwSccStatus = new uint[1];
GetSccGlyph(1, new[] { itemFilePath }, rgsiGlyphs, rgdwSccStatus);
hierarchy.SetProperty(itemId, (int)__VSHPROPID.VSHPROPID_StateIconIndex, rgsiGlyphs[0]);

где itemId - идентификатор конкретного элемента проекта. К сожалению, этот подход работает только для решения, но не обновляет глифы для типов элементов проекта/класса. Я читал, что есть еще один способ принудительного обновления глифов для всех дочерних элементов проекта.

sccProject2.SccGlyphChanged(0, null, null, null);

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

Я знаю, что это возможно, потому что VisualSvn и другие подобные плагины каким-то образом динамически обновляют глифы. Кто-нибудь решил эту проблему?


person Andrew    schedule 25.06.2012    source источник


Ответы (1)


Если у вас есть пакет, вы должны реализовать Иерархия IVs. При этом необходимо реализовать AdviseHiearchyEvents. В этом методе вы должны добавить переданный приемник в коллекцию, которую вы храните, примерно так:

    int IVsUIHierarchy.AdviseHierarchyEvents(IVsHierarchyEvents eventSink, out uint cookie)
    {
        cookie = _sinkCookie++; // come up with some unique cookie
        _eventSinks.Add(cookie, eventSink); // remember this sink
        return VSConstants.S_OK;
    }

    int IVsUIHierarchy.UnadviseHierarchyEvents(uint cookie)
    {
        _eventSinks.Remove(cookie);
        return VSConstants.S_OK;
    }

И теперь вы можете вызывать события изменения свойства, когда вам нужно, например:

    private void NotifySccChange()
    {
        foreach (sink in _eventSinks)
        {
            try
            {

                sink.OnPropertyChanged(MyId, (int)__VSHPROPID.VSHPROPID_StateIconIndex, 0);
            }
            catch (Exception e)
            {
                SinkIsDead(sink);
            }
        }
    }
person Simon Mourier    schedule 15.07.2013