Autor Beitrag
MBreuer2
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Mo 24.06.13 18:01 
Hallo,

ich habe ein Addin in c# begonnen mit dem ich Quellcode verändern möchte.
Den ersten Schritt habe ich schon geschafft, ich kann einen Text bei der Cursorposition einstellen.

Jetzt möchte ich gern wissen zu welchem Namespace diese Cursorposition gehört,
ich habe mit folgendem Code

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
CodeElements elements = _applicationObject.ActiveDocument.ProjectItem.FileCodeModel.CodeElements;
foreach (CodeElement element in elements)
{
    if (element.Kind == vsCMElement.vsCMElementNamespace)
    {
         CodeNamespace ns = (CodeNamespace)element;
         MeinEditPoint.Insert("Namespace: " + ns.FullName);
    }
}

geschafft einen Namespace zu erkennen.
Leider habe ich geschachtelte Namespaces noch nicht erkannt und außerdem kann es ja sein das die Datei mehrere Namespaces enthält.
Also: den voll qualifizierten Namespace an der Cursorposition muss ich ermitteln.

Kann mir bitte jemand mit einem einfachen Codeschnipsel helfen ?

Danke

Moderiert von user profile iconTh69: Codeformatierung überarbeitet.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 24.06.13 18:47 
Hallo,

direkt habe ich zwar keine Antwort auf deine Frage, aber unter Resources about Visual Studio .NET extensibility (Abschnitt "Articles about the code model:") gibt es eine Reihe von Artikel darüber, u.a. HOWTO: Navigate the code elements of a file from a Visual Studio .NET macro or add-in.

So wie ich das verstehe müßtest du also rekursiv die CodeElements Member durchsuchen und dir jeweils den aktuellen Namespace und Class merken (bis du konkret dein Element an Cursorposition findest). Evtl. kommst du aber mittels des Parent-Elements direkt an die Klasse und den Namensbereich (welches die Sache stark vereinfachen würde).

P.S. Die Codebeispiele in den Artikeln sind zwar in VB.NET, aber lassen sich ja 1:1 nach C# umformen.
MBreuer2 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Di 25.06.13 15:29 
Danke für den Hinweis,

ich habe im Netz etwas code gefunden und angepasst.
Die Funktion GetCodeElementAtCursor liefert einen string mit dem Namespace.
Sicher lässt sich durch verändern von aSearchElement auch nach anderen Elementen suchen.

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
#region code to get the namespace
        /// <summary>
        /// get a codeelement which is located at the current cursor position
        /// currently a namespace is searched
        /// </summary>
        /// <returns></returns>
        private string GetCodeElementAtCursor()
        {
            vsCMElement aSearchElement = vsCMElement.vsCMElementNamespace;
            string aResult = string.Empty;
            EnvDTE.CodeElement aObjCodeElement = null;
            EnvDTE.TextPoint aObjCursorTextPoint;
            try
            {
                aObjCursorTextPoint = GetCursorTextPoint();
                if (!(aObjCursorTextPoint == null))
                {
                    aObjCodeElement = GetCodeElementAtTextPoint(aSearchElement, _applicationObject.ActiveDocument.ProjectItem.FileCodeModel.CodeElements, aObjCursorTextPoint);
                }
                if (null != aObjCodeElement)
                {
                    aResult = aObjCodeElement.FullName;
                }
            }
            catch (System.Exception )
            {
                //handle the exception
            }
            return aResult;
        }

        /// <summary>
        /// define the current cursor position
        /// </summary>
        /// <returns></returns>
        private EnvDTE.TextPoint GetCursorTextPoint()
        {
            EnvDTE.TextPoint aObjCursorTextPoint = null;
            try
            {
                aObjCursorTextPoint = ((EnvDTE.TextDocument)((EnvDTE80.DTE2)_applicationObject).ActiveDocument.Object("textdocument")).Selection.ActivePoint;
            }
            catch (System.Exception )
            {
                //handle the exception
            }
            return aObjCursorTextPoint;
        }

        /// <summary>
        /// get the requested code element at the text point
        /// </summary>
        /// <param name="theRequestedCodeElementKind">the code element to get</param>
        /// <param name="theColCodeElements"></param>
        /// <param name="theObjTextPoint">the current text point</param>
        /// <returns></returns>
        private EnvDTE.CodeElement GetCodeElementAtTextPoint(EnvDTE.vsCMElement theRequestedCodeElementKind, EnvDTE.CodeElements theColCodeElements, EnvDTE.TextPoint theObjTextPoint)
        {
            EnvDTE.CodeElement aObjResultCodeElement = null;
            EnvDTE.CodeElements aColCodeElementMembers;
            EnvDTE.CodeElement aObjMemberCodeElement;
            if (!(theColCodeElements == null))
            {
                foreach (EnvDTE.CodeElement aObjCodeElement in theColCodeElements)
                {
                    if (aObjCodeElement.StartPoint.GreaterThan(theObjTextPoint))
                    {
                        //  The code element starts beyond the point
                    }
                    else if (aObjCodeElement.EndPoint.LessThan(theObjTextPoint))
                    {
                        //  The code element ends before the point
                    }
                    else
                    {
                        //  The code element contains the point
                        if ((aObjCodeElement.Kind == theRequestedCodeElementKind))
                        {
                            //  Found
                            aObjResultCodeElement = aObjCodeElement;
                        }
                        //  recursive to get nested
                        aColCodeElementMembers = aObjCodeElement.Children;
                        aObjMemberCodeElement = GetCodeElementAtTextPoint(theRequestedCodeElementKind, aColCodeElementMembers, theObjTextPoint);
                        if (!(aObjMemberCodeElement == null))
                        {
                            aObjResultCodeElement = aObjMemberCodeElement;
                        }
                        break;
                    }
                }
            }
            return aObjResultCodeElement;
        }
#endregion