Search code examples
visual-studiomefvisual-studio-extensions

How to get Current ActiveDocument in Visual Studio Extension using MEF?


I'm working on Visual Studio 2013 Extension using MEF while trying to read Active Document Content Type and Code. Presently it only reads at Opening Time of the Document/ProjectItem in the Editor. Once these are opened, it doesn't read these again whenever we switch between opened Document Tabs.

Requirement: I want this extension to read the Content Type and Code Text of current Active Document.

Updated:
Problem: I know, using EnvDTE80.DTE2.ActiveWindow, I can get currently focused document, but I'm confused here that how to call this code to read the Currently Active Document/Window things? Let's say if we have 10 Documents, the active document (which got current focus) needs to be read by the this extension. And here VsTextViewCreated is only called whenever we open a new document or the one closed before i.e Text View is Created. It won't be called upon already open documents (i.e. Text View already created) and so we won't be able to get updated wpfTextView object upon moving the focus on other already open documents. And I'm confused here how to call this using DTE2.ActiveDocument or DTE2.ActiveWindow event handlers.

Question:
Is this possible in MEF, without using DTE?
Is there any Interface dealing with TextViews already present in VS editor?

Here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading.Tasks;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Text.Editor;

using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Utilities;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using System.Diagnostics;

namespace VSIXProject_Test
{
    [Export(typeof(IVsTextViewCreationListener))]
    [ContentType("code")]
    [TextViewRole(PredefinedTextViewRoles.Editable)]
    class VsTextViewCreationListener : IVsTextViewCreationListener
    {
        [Import]
        IVsEditorAdaptersFactoryService AdaptersFactory = null;

        public void VsTextViewCreated(IVsTextView textViewAdapter)
        {
            var wpfTextView = AdaptersFactory.GetWpfTextView(textViewAdapter);
            if (wpfTextView == null)
            {
                Debug.Fail("Unable to get IWpfTextView from text view adapter");
                return;
            }

            Debug.Write(wpfTextView.TextBuffer.ContentType.TypeName);
        }
    }
}

Solution

  • Fortunately, I got what I was trying to achieve. A helper solution is already posted here: I used the helper method in dte2.Events.WindowsEvents.WindowActived and getting IVsTextView object to retrieve the Text Buffer. Here is my Code snippet of WindowActivated event:

    void WindowEvents_WindowActivated(EnvDTE.Window GotFocus, EnvDTE.Window LostFocus)
        {
    
            if (null != GotFocus.Document)
            {
                Document curDoc = GotFocus.Document;
                Debug.Write("Activated : " + curDoc.FullName);
                this.IvsTextView=GetIVsTextView(curDoc.FullName); //Calling the helper method to retrieve IVsTextView object.
                if (IvsTextView != null)
                {
                    IvsTextView.GetBuffer(out curDocTextLines); //Getting Current Text Lines 
    
                    //Getting Buffer Adapter to get ITextBuffer which holds the current Snapshots as wel..
                    Microsoft.VisualStudio.Text.ITextBuffer curDocTextBuffer = AdaptersFactory.GetDocumentBuffer(curDocTextLines as IVsTextBuffer); 
                    Debug.Write("\r\nContentType: "+curDocTextBuffer.ContentType.TypeName+"\nTest: " + curDocTextBuffer.CurrentSnapshot.GetText());
    
                }
            }
        }
    

    This is now working with all the code documents opened in VS Editor. Hope this would help others like me.