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

1

4

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);
        }
    }
}
Doubtful answered 11/6, 2014 at 13:17 Comment(6)
Why? Once you know the active document, what would you do with it?Royalty
@JasonMalinowski Because 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. It would not be called upon already open documents and so we won't be able to get updated wpfTextView object. And I'm confused how to call this using DTE2.ActiveDocument or DTE2.ActiveWindow event handlers.Doubtful
@JasonMalinowski Thanks for the Pushing Comment :)Doubtful
I'm not sure what you mean by "already open" documents -- your creation listener is registered at the start of VS, there's no concept of a "missed" open.Royalty
I also wasn't sure if IWpfTextView.GotAggregateFocus/IWpfTextView.LostAggregateFocus might actually do what you really need, if you just need to know which view has focus. There's also an important subtlety here of "view" vs. "window" which needs to be carefully considered.Royalty
See the answer. Getting the document opened and reading the focused one (focused or activated tab) to get its snapshots. If focused is moved to other tab, able to read snapshot there.Doubtful
D
5

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.

Doubtful answered 11/6, 2014 at 13:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.