【问题标题】:In Visual Studio Add In - How can I retrieve the properties of the text selection's object (Visual Commander)在 Visual Studio 中添加 - 如何检索文本选择对象的属性 (Visual Commander)
【发布时间】:2014-09-08 12:24:06
【问题描述】:

我为此挠了一天多:

基本上我正在尝试为 Visual Studio 2012 构建一个加载项,它执行以下操作:

取当前选择的变量名,找到它作为实例的类,然后在自己的行中为每个属性键入veriable.property:

之前:

例如。 (考虑选择了 myPerson)

int CountPerson(Person myPerson)
{
    *myPerson*
}

之后:

int CountPerson(Person myPerson)
{
    myPerson.Name
    myPerson.Surname
    myPerson.Age
}

我在 stackoverflow 上问了一个类似的问题,并得到了我现在正在追求的答案。 Visual Studio dump all properties of class into editor

这是目前为止的源代码:

using EnvDTE;
using EnvDTE80;
using System;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;


public class C : VisualCommanderExt.ICommand
{
    public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package) 
    {
        EnvDTE.TextSelection ts = DTE.ActiveWindow.Selection as EnvDTE.TextSelection;
        if (ts == null)
            return;

        EnvDTE.CodeClass codeClass = ts.ActivePoint.CodeElement[vsCMElement.vsCMElementClass]   as     EnvDTE.CodeClass;
        if (codeClass == null)
            return;

        string properties = "";
        foreach (CodeElement elem in codeClass.Members)
        {
            if (elem.Kind == vsCMElement.vsCMElementProperty)
                properties += elem.Name + System.Environment.NewLine;
        }
        ts.Text = properties;   

    }
}

这工作得很好,除了它完全忽略选定的文本,而是打印当前类的属性。我需要我选择的变量的类的属性。

如果这样会让事情变得更容易的话,我会接受输入“Person”而不是 |myPerson。

我在互联网上找到了以下链接,但无法实现逻辑: http://blogs.clariusconsulting.net/kzu/how-to-get-a-system-type-from-an-envdte-codetyperef-or-envdte-codeclass/ http://www.visualstudioextensibility.com/2008/03/06/how-do-i-get-a-system-type-from-a-type-name/

他们可能会帮助你帮助我吗?

【问题讨论】:

  • 您是否成功创建了扩展程序?你把它放到 Visual Studio 库了吗?
  • 下面的代码是我所能得到的,我最终放弃了,没有它就活了
  • 您是否介意再帮我一些忙?
  • 我自己做了一个对Visual Studio的扩展,在这里我得到了当前选择所在的类名和方法名。我在GitHub上有源,它叫CopyForReview可能正在浏览它的源可以帮到你吗?
  • 谢谢,会的! :)

标签: c# visual-studio visual-studio-2012 add-in


【解决方案1】:

您可以将光标设置在函数定义行中的函数参数名称上,并使用以下代码生成属性列表:

(添加对 Microsoft.VisualStudio.Shell.Design 的引用)

public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package) 
{
    EnvDTE.TextSelection ts = DTE.ActiveWindow.Selection as EnvDTE.TextSelection;
    if (ts == null)
        return;

    EnvDTE.CodeParameter codeParam = ts.ActivePoint.CodeElement[vsCMElement.vsCMElementParameter] as EnvDTE.CodeParameter;
    if (codeParam == null)
        return;

    System.Type tClass = GetTypeByName(DTE, package, codeParam.Type.AsFullName);
    string properties = "";
    foreach (var p in tClass.GetProperties())
    {
            properties += codeParam.Name + "." + p.Name + System.Environment.NewLine;
    }
    System.Windows.Clipboard.SetText(properties);
    System.Windows.MessageBox.Show(properties);
}

private System.Type GetTypeByName(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package, string name)
{
    System.IServiceProvider serviceProvider = package as System.IServiceProvider;
    Microsoft.VisualStudio.Shell.Design.DynamicTypeService typeService = 
        serviceProvider.GetService(typeof(Microsoft.VisualStudio.Shell.Design.DynamicTypeService)) as
        Microsoft.VisualStudio.Shell.Design.DynamicTypeService;

    Microsoft.VisualStudio.Shell.Interop.IVsSolution sln = 
        serviceProvider.GetService(typeof(Microsoft.VisualStudio.Shell.Interop.IVsSolution)) as
        Microsoft.VisualStudio.Shell.Interop.IVsSolution;

    Microsoft.VisualStudio.Shell.Interop.IVsHierarchy hier;
    sln.GetProjectOfUniqueName(DTE.ActiveDocument.ProjectItem.ContainingProject.UniqueName, out hier);

    return typeService.GetTypeResolutionService(hier).GetType(name, true);
}

【讨论】:

  • 哇,这太棒了,非常接近我正在寻找的东西。唯一的区别是光标的放置和输出位置。为什么一定要在功能线上?
  • 好的,我设法将结果放入方法中:ts.LineDown();ts.LineDown();ts.StartOfLine();ts.Insert(properties);
  • 所以剩下的唯一问题就是使用代码中选择的变量,而不是强制用户选择函数参数
  • @user230910:两行向下移动到函数体?如果打开 { 与方法签名在同一行怎么办?
  • @user230910 Visual Studio 代码模型不支持局部变量,这就是我使用函数声明的原因。也许可以使用额外的命令代码从选定的变量名称转到函数参数。
【解决方案2】:

好的,感谢上面的 Sergey,我现在有了以下代码,可以回答我的大部分问题:

using EnvDTE;
using EnvDTE80;
using System;

public class C : VisualCommanderExt.ICommand
{
        public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package) 
        {
            EnvDTE.TextSelection ts = DTE.ActiveWindow.Selection as EnvDTE.TextSelection;
            if (ts == null)
                    throw new Exception("No Selection");

                EnvDTE.CodeParameter codeParam = ts.ActivePoint.CodeElement[vsCMElement.vsCMElementParameter] as EnvDTE.CodeParameter;
                if (codeParam == null)
                    throw new Exception("Not Parameter");

                System.Type tClass = GetTypeByName(DTE, package, codeParam.Type.AsFullName);
                string properties = System.Environment.NewLine;
                foreach (var p in tClass.GetProperties())
                {
                    properties += codeParam.Name + "." + p.Name + System.Environment.NewLine;
                }

                // Move into the method and dump the properties there
                ts.FindText("{");
                ts.Insert("{" + properties);
            }


    private System.Type GetTypeByName(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package, string name)
    {
        System.IServiceProvider serviceProvider = package as System.IServiceProvider;
        Microsoft.VisualStudio.Shell.Design.DynamicTypeService typeService = 
            serviceProvider.GetService(typeof(Microsoft.VisualStudio.Shell.Design.DynamicTypeService)) as
                Microsoft.VisualStudio.Shell.Design.DynamicTypeService;

        Microsoft.VisualStudio.Shell.Interop.IVsSolution sln = serviceProvider.GetService(typeof(Microsoft.VisualStudio.Shell.Interop.IVsSolution)) as
            Microsoft.VisualStudio.Shell.Interop.IVsSolution;

        Microsoft.VisualStudio.Shell.Interop.IVsHierarchy hier;
        sln.GetProjectOfUniqueName(DTE.ActiveDocument.ProjectItem.ContainingProject.UniqueName, out hier);

        return typeService.GetTypeResolutionService(hier).GetType(name, true);
    }
}

当前问题:

    * It doesnt work for a variable in the code only for function parameters

我发现这可能会有所帮助:(尽管代码超出了我的技能范围) Auto generate properties when creating object

【讨论】:

    猜你喜欢
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多