C# 在Visual Studio加载项中-如何检索文本选择对象的属性(Visual Commander)
一天多来,我一直在为这件事挠头: 实际上,我正在尝试为Visual Studio 2012构建一个外接程序,该外接程序执行以下操作: 使用当前选定的变量名,查找它是其实例的类,然后在其自己的行中为每个属性键入veriable.property: 之前: 认为我被选中了C# 在Visual Studio加载项中-如何检索文本选择对象的属性(Visual Commander),c#,visual-studio,visual-studio-2012,add-in,C#,Visual Studio,Visual Studio 2012,Add In,一天多来,我一直在为这件事挠头: 实际上,我正在尝试为Visual Studio 2012构建一个外接程序,该外接程序执行以下操作: 使用当前选定的变量名,查找它是其实例的类,然后在其自己的行中为每个属性键入veriable.property: 之前: 认为我被选中了 int CountPerson(Person myPerson) { *myPerson* } 之后: int CountPerson(Person myPerson) { myPerson.Name m
int CountPerson(Person myPerson)
{
*myPerson*
}
之后:
int CountPerson(Person myPerson)
{
myPerson.Name
myPerson.Surname
myPerson.Age
}
我在这里就stackoverflow提出了一个类似的问题,并得到了我现在正在寻求的答案。
以下是到目前为止的源代码:
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;
}
}
除了完全忽略选定的文本,而是打印当前类的属性之外,这种方法工作得非常好。我需要选择的变量类的属性
我将和打字的人而不是我的人生活在一起,如果这能让事情变得更容易的话
我在互联网上找到了以下链接,但无法实现逻辑:
它们可能会帮助您帮助我?您可以在函数定义行中的函数参数名称上设置光标,并使用以下代码生成属性列表: 添加对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);
}
好的,感谢上面的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
我发现这可能会有所帮助:虽然代码超出了我的技能范围
哇,这太棒了,非常接近我要找的东西。唯一的区别是光标的位置和输出位置。为什么它必须在函数行上?好的,我设法将结果输入到方法中:ts.LineDown;ts.LineDown;星线;插入属性;因此,剩下的唯一问题是使用代码中选择的变量,而不是强制用户选择函数parameter@user230910:两行向下移动到功能体?如果打开了怎么办{是否与方法签名在同一行?@user230910 Visual Studio代码模型不支持局部变量,这就是我使用函数声明的原因。也许可以使用其他命令代码从所选变量名转到函数参数。您是否成功创建了扩展名?是否已将其放到Visua上l Studio gallery还没有?下面的代码是我所能得到的,我最终放弃了,没有了它就生活了如果你介意帮我做更多的话?我自己做了一个Visual Studio的扩展,在那里我得到了当前选择所在的类名和方法名。我在GitHub上有源代码,它叫浏览,可能是我可以帮你吗?谢谢,我会帮你的