【问题标题】:Implement "Navigation bar" for custom editor为自定义编辑器实现“导航栏”
【发布时间】:2014-02-21 11:11:51
【问题描述】:

注册自定义语言服务扩展时,Visual Studio 会在 Text Editor 节点(在 Visual Studio 选项对话框中)为该语言创建一个新选项条目。在该节点下方创建了两个默认节点,名为 GeneralTabs,其中 General 选项卡包含语句完成和显示设置...

Dispay 组中有三个选项;其中之一是Navigation Bar 复选框(显示/隐藏编辑器的导航栏)。对于我的自定义语言服务,此选项已禁用。当然,它还没有实现。

我想知道,我必须做什么,为我的自定义编辑器提供导航栏...我想我必须在编辑器的工厂或语言服务中实现某个接口包必须导出某个 MEF 组件,或者,或者,...

【问题讨论】:

  • 事实证明,您确实需要注册一个空闲计时器才能让此功能正常执行。完成此操作后,您将收到对 OnSynchronizeDropdowns 的调用,并且还会收到带有 ParseReasonCheckParseSource 调用(如果您想显示错误,则需要)。

标签: visual-studio-extensions vsx vs-extensibility vspackage visual-studio-sdk


【解决方案1】:

Jon Senchyna 的回答引导我走向正确的方向。 OnSynchronizeDropdowns 方法永远不会被调用(SDK 文档在这种情况下是错误的)。最后的技巧是覆盖至少GetComboAttributesGetEntryAttributesGetEntryText 以获得两个组合框的纯文本项...

[ComVisible(true)]
public sealed class CustomTypeAndMemberDropdownBars : TypeAndMemberDropdownBars
{
    private readonly IList<string> declarations;

    private readonly IList<string> members;

    public CustomTypeAndMemberDropdownBars(
        LanguageService languageService, 
        IVsTextView view)
        : base(languageService)
    {
        // TODO: initialize declarations and members from the given text view...
        this.declarations = ...
        this.members = ...
    }

    private enum ComboIndex
    {
        Types = 0, 

        Members = 1
    }

    public override int GetComboAttributes(
        int combo, 
        out uint entries, 
        out uint entryType, 
        out IntPtr imageList)
    {
        entries = 0;
        imageList = IntPtr.Zero;

        entryType = (uint)DROPDOWNENTRYTYPE.ENTRY_TEXT;

        var comboType = (ComboIndex)combo;
        switch (comboType)
        {
            case ComboIndex.Types:
                entries = (uint)this.declarations.Count();
                break;

            case ComboIndex.Members:
                entries = (uint)this.members.Count();
                break;
        }

        return VSConstants.S_OK;
    }

    public override int GetEntryAttributes(
        int combo, 
        int entry, 
        out uint fontAttrs)
    {
        fontAttrs = (uint)DROPDOWNFONTATTR.FONTATTR_PLAIN;

        return VSConstants.S_OK;
    }

    public override int GetEntryText(
        int combo, 
        int entry, 
        out string text)
    {
        text = null;
        var comboType = (ComboIndex)combo;
        switch (comboType)
        {
            case ComboIndex.Types:
                text = this.declarations[entry];
                break;

            case ComboIndex.Members:
                text = this.members[entry];
                break;
        }

        return VSConstants.S_OK;
    }

    public override bool OnSynchronizeDropdowns(
        LanguageService languageService, 
        IVsTextView textView, 
        int line, 
        int col, 
        ArrayList dropDownTypes, 
        ArrayList dropDownMembers, 
        ref int selectedType, 
        ref int selectedMember)
    {
        return false;
    }
}

【讨论】:

  • 出于好奇,如果您在LanguageServiceGetLanguagePreferences 函数中将myLanguagePreference.ShowNavigationBar 设置为trueOnSynchronizeDropdowns 会被调用吗?
  • 另外,您如何提供服务?我在互联网上找到了两种完成方法。一种是添加ServiceCreatorCallback。另一种方法是通过SOleComponentManager 注册它。我发现使用第一种方式导致我的很多LanguageServices 功能无法正常工作,包括导航栏。
  • 在语言首选项中将ShowNavigationBar 属性强制为true 不会导致调用OnSynchronizeDropdowns 方法。
  • 我在我的包的Initialize 方法中注册了语言服务。我将当前的VsPackage 实例转换为IServiceContainer,然后调用AddService 来提升语言服务实例。
  • 我打开了一个新的question,以了解为什么导航栏(和许多其他功能)仅在“旧方式”提供服务时才有效。
【解决方案2】:

我相信以下步骤应该是您需要的:

  1. Package 类中,将ProvideLanguageService 属性中的ShowDropDownOptions 属性设置为true
  2. 创建一个实现TypeAndMemberDropdownBars的类
  3. 在您的LanguageService 类中,实现CreateDropDownHelper 函数并让它返回您的TypeAndMemberDropdownBars 的一个实例

【讨论】:

  • 这允许我显示和隐藏导航栏,但组合框始终保持为空;我的TypeAndMemberDropdownBars 实现的OnSynchronizeDropdowns 方法永远不会被调用。
  • 我之前也遇到过同样的问题。我现在无法访问代码,但我明天会看看它,然后告诉你我做了什么。
  • 你能用CreateDropDownHelper的实现更新你的问题吗?
  • 我想我找到了丢失的步骤。在我的GetLanguagePreferences 实现中,我不得不将ShowNavigationBar 属性强制为true
  • 据我所知,ShowDropDownOptions 切换“导航栏”选项是否可以在选项 GUI 中选择,但是否选中则存储在 registry 中跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 2012-10-12
  • 1970-01-01
相关资源
最近更新 更多