演练:使用编辑器扩展的快捷键

可以响应在编辑器扩展的快捷键。 使用快捷键,下面的演练演示如何将视图修饰到文本视图。 本演练基于视区修饰编辑模板,因此,它允许您添加修饰使用 + 字符。

系统必备

若要完成本演练,您必须安装 Visual Studio 2010 SDK。

备注

有关 Visual Studio SDK 的更多信息,请参见 扩展 Visual Studio 概述。若要查找有关中所列如何下载 Visual Studio SDK,请 Visual Studio Extensibility Developer Center 参见 MSDN 网站上。

创建一个 managed extensibility framework 项目 (MEF)

创建 MEF 项目

  1. 创建一个编辑视区修饰项目。 将解决方案命名为 KeyBindingTest。

  2. 打开在 VSIX 清单编辑器中的 source.extension.vsixmanifest 文件。

  3. 确保 Content 归为包含一个 MEF 组件内容类型,而 Path 设置为 KeyBindingTest.dll。

  4. 保存并关闭的 Source.extension.vsixmanifest。

  5. 将下列引用添加并将 CopyLocal 到 false:

    Microsoft.VisualStudio.Editor

    Microsoft.VisualStudio.OLE.Interop

    Microsoft.VisualStudio.Shell

    Microsoft.VisualStudio.TextManager.Interop

  6. 删除 KeyBindingTestFactory 类文件。

在 KeyBindingTest 类文件中,更改类名称。 PurpleCornerBox。 更改构造函数。 在构造函数中,将行:

_adornmentLayer = view.GetAdornmentLayer("KeyBindingTest")
_adornmentLayer = view.GetAdornmentLayer("KeyBindingTest");

设置为

_adornmentLayer = view.GetAdornmentLayer("PurpleCornerBox")
_adornmentLayer = view.GetAdornmentLayer("PurpleCornerBox");

定义命令筛选器

命令筛选器是 IOleCommandTarget的实现中,处理命令通过实例化修饰。

定义命令筛选器

  1. 将类文件并将其命名为 KeyBindingCommandFilter。

  2. 使用语句,添加以下内容。

    Imports System
    Imports System.Runtime.InteropServices
    Imports Microsoft.VisualStudio.OLE.Interop
    Imports Microsoft.VisualStudio
    Imports Microsoft.VisualStudio.Text.Editor
    
    using System;
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Text.Editor;
    
  3. 名为 KeyBindingCommandFilter 的类应从 IOleCommandTarget继承。

    Friend Class KeyBindingCommandFilter
        Implements IOleCommandTarget
    
    internal class KeyBindingCommandFilter : IOleCommandTarget
    
  4. 添加文本视图、下一个命令在命令字符串和标志的私有字段可以表示命令筛选器是否已经添加了。

    Private m_textView As IWpfTextView
    Friend m_nextTarget As IOleCommandTarget
    Friend m_added As Boolean 
    Friend m_adorned As Boolean
    
    private IWpfTextView m_textView;
    internal IOleCommandTarget m_nextTarget;
    internal bool m_added;
    internal bool m_adorned;
    
  5. 添加用于设置文本视图的构造函数。

    Public Sub New(ByVal textView As IWpfTextView)
        m_textView = textView
        m_adorned = False 
    End Sub
    
    public KeyBindingCommandFilter(IWpfTextView textView)
    {
        m_textView = textView;
        m_adorned = false;
    }
    
  6. 按如下方式执行 QueryStatus() 方法。

    Private Function QueryStatus(ByRef pguidCmdGroup As Guid, ByVal cCmds As UInteger, ByVal prgCmds() As OLECMD, ByVal pCmdText As IntPtr) As Integer Implements IOleCommandTarget.QueryStatus
        Return m_nextTarget.QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText)
    End Function
    
    int IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
        return m_nextTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
    }
    
  7. 执行 Exec() 方法,使其添加一个紫色框到视图,如果 + 键入字符。

    Private Function Exec(ByRef pguidCmdGroup As Guid, ByVal nCmdID As UInteger, ByVal nCmdexecopt As UInteger, ByVal pvaIn As IntPtr, ByVal pvaOut As IntPtr) As Integer Implements IOleCommandTarget.Exec
        If m_adorned = False Then 
            Dim typedChar As Char = Char.MinValue
    
            If pguidCmdGroup = VSConstants.VSStd2K AndAlso nCmdID = CUInt(VSConstants.VSStd2KCmdID.TYPECHAR) Then
                typedChar = CChar(ChrW(Marshal.GetObjectForNativeVariant(pvaIn)))
                If typedChar.Equals("+"c) Then 
                    Dim TempPurpleCornerBox As PurpleCornerBox = New PurpleCornerBox(m_textView)
                    m_adorned = True 
                End If 
            End If 
        End If 
        Return m_nextTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)
    End Function
    
    int IOleCommandTarget.Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
    {
        if (m_adorned == false)
        {
            char typedChar = char.MinValue;
    
            if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                if (typedChar.Equals('+'))
                {
                    new PurpleCornerBox(m_textView);
                    m_adorned = true;
                }
            }
        }
        return m_nextTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
    }
    

将命令添加筛选器提供程序

修饰提供程序必须将命令添加筛选器。文本视图。 在此示例中,提供程序实现 IVsTextViewCreationListener 侦听文本视图创建事件。 修饰提供程序导出修饰层,定义修饰的 Z 顺序。

将命令添加筛选器提供程序

  1. 将类文件并将其命名为 KeyBindingFilterProvider。

  2. 使用语句,添加以下内容。

    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel.Composition
    Imports Microsoft.VisualStudio
    Imports Microsoft.VisualStudio.OLE.Interop
    Imports Microsoft.VisualStudio.Utilities
    Imports Microsoft.VisualStudio.Editor
    Imports Microsoft.VisualStudio.Text.Editor
    Imports Microsoft.VisualStudio.TextManager.Interop
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio.Utilities;
    using Microsoft.VisualStudio.Editor;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.TextManager.Interop;
    
  3. 添加从 IVsTextViewCreationListener从继承的名为 KeyBindingFilterProvider 的类,并将其导出与 “text”内容类型和 EditableTextViewRoleAttribute

    <Export(GetType(IVsTextViewCreationListener)), ContentType("text"), TextViewRole(PredefinedTextViewRoles.Editable)>
    Friend Class KeyBindingCommandFilterProvider
        Implements IVsTextViewCreationListener
    
    [Export(typeof(IVsTextViewCreationListener))]
    [ContentType("text")]
    [TextViewRole(PredefinedTextViewRoles.Editable)]
    internal class KeyBindingCommandFilterProvider : IVsTextViewCreationListener
    
  4. 添加修饰层定义。

    <Export(GetType(AdornmentLayerDefinition)), Name("PurpleCornerBox"), Order(), TextViewRole(PredefinedTextViewRoles.Editable)>
    Friend keybindingAdornmentLayer As AdornmentLayerDefinition
    
    [Export(typeof(AdornmentLayerDefinition))]
    [Name("PurpleCornerBox")]
    [Order()]
    [TextViewRole(PredefinedTextViewRoles.Editable)]
    internal AdornmentLayerDefinition keybindingAdornmentLayer;
    
  5. 获取文本视图适配器,必须导入 IVsEditorAdaptersFactoryService

    <Import(GetType(IVsEditorAdaptersFactoryService))>
    Friend editorFactory As IVsEditorAdaptersFactoryService = Nothing
    
    [Import(typeof(IVsEditorAdaptersFactoryService))]
    internal IVsEditorAdaptersFactoryService editorFactory = null;
    
  6. 执行 VsTextViewCreated 方法,使其添加 KeyBindingCommandFilter

    Public Sub VsTextViewCreated(ByVal textViewAdapter As IVsTextView) Implements IVsTextViewCreationListener.VsTextViewCreated
        Dim textView As IWpfTextView = editorFactory.GetWpfTextView(textViewAdapter)
        If textView Is Nothing Then 
            Return 
        End If
    
        AddCommandFilter(textViewAdapter, New KeyBindingCommandFilter(textView))
    End Sub
    
    public void VsTextViewCreated(IVsTextView textViewAdapter)
    {
        IWpfTextView textView = editorFactory.GetWpfTextView(textViewAdapter);
        if (textView == null)
            return;
    
        AddCommandFilter(textViewAdapter, new KeyBindingCommandFilter(textView));
    }
    
  7. AddCommandFilter 处理程序获取文本视图适配器并添加命令筛选器。

    Private Sub AddCommandFilter(ByVal viewAdapter As IVsTextView, ByVal commandFilter As KeyBindingCommandFilter)
        If commandFilter.m_added = False Then 
            'get the view adapter from the editor factory 
            Dim [next] As IOleCommandTarget
            Dim hr As Integer = viewAdapter.AddCommandFilter(commandFilter, [next])
    
            If hr = VSConstants.S_OK Then
                commandFilter.m_added = True 
                'you'll need the next target for Exec and QueryStatus 
                If [next] IsNot Nothing Then
                    commandFilter.m_nextTarget = [next]
                End If 
            End If 
        End If 
    End Sub
    
    void AddCommandFilter(IVsTextView viewAdapter, KeyBindingCommandFilter commandFilter)
    {
        if (commandFilter.m_added == false)
        {
            //get the view adapter from the editor factory
            IOleCommandTarget next;
            int hr = viewAdapter.AddCommandFilter(commandFilter, out next);
    
            if (hr == VSConstants.S_OK)
            {
                commandFilter.m_added = true;
                //you'll need the next target for Exec and QueryStatus 
                if (next != null)
                    commandFilter.m_nextTarget = next;
            }
        }
    }
    

生成并测试代码

若要测试此代码,请生成 KeyBindingTest 解决方案并运行在的实验实例。

生成和测试 KeyBindingTest 解决方案

  1. 生成解决方案。

  2. 当您运行在调试器中查看此项目, Visual Studio 的第二个实例进行实例化。

  3. 创建或打开一个文本文件,然后单击任意位置在文本视图。

  4. 类型 +。

    调整文本视图。

    一个紫色正方形应出现在文本视图的右上角。

请参见

任务

演练:链接到文件扩展名的内容类型