Visual studio 如何使用UITypeEditor为Visual Studio创建简单的自动化扩展程序
在Visual Studio中,当您在解决方案资源管理器中选择一个或多个项目项时,有时您可能希望将自定义属性添加到属性窗口(按F4时弹出的窗口)。另外,为了填充这些属性的值,我需要添加一个按钮来弹出一个表单,这样我就可以在设计时从用户那里收集信息 什么是最简单的实现,这样我就可以开始了? 如何使用UITypeEditAttribute创建用户界面来收集值?这是我能想到的最简单的实现 由于这是一个高级主题,这意味着您在开始实施之前完成所有步骤都会感到舒适。这些都是常见的编程任务 如果有什么不清楚的地方,请发表评论,我会尽量简化。注意,这被配置为在VisualStudio中为Visual C文件创建自定义属性。当运行或调试visual studio包,然后单击任何.cs文件时,自定义属性应显示在“属性”窗口中。提供的意见是必要的说明 创建一个VisualStudio包。 创建一个接口,该接口实现要添加到属性页的自定义属性。 创建一个实现自定义属性接口的类,并用属性装饰自定义属性。 创建实现IExtenderProvider接口并重写GetExtender和CanExtend方法的类。 创建从UITypeEditor继承的新类,并重写GetEditStyle和EditValue方法。 让我们开始吧 一,。在VisualStudio中创建包 Package.csVisual studio 如何使用UITypeEditor为Visual Studio创建简单的自动化扩展程序,visual-studio,ide,extensibility,Visual Studio,Ide,Extensibility,在Visual Studio中,当您在解决方案资源管理器中选择一个或多个项目项时,有时您可能希望将自定义属性添加到属性窗口(按F4时弹出的窗口)。另外,为了填充这些属性的值,我需要添加一个按钮来弹出一个表单,这样我就可以在设计时从用户那里收集信息 什么是最简单的实现,这样我就可以开始了? 如何使用UITypeEditAttribute创建用户界面来收集值?这是我能想到的最简单的实现 由于这是一个高级主题,这意味着您在开始实施之前完成所有步骤都会感到舒适。这些都是常见的编程任务 如果有什么不清楚的
// ...
public sealed class ThePackage : Package
{
private DTE2 Host;
private ObjectExtenders _extensionManager;
private MyExtenderProvider _extenderProvider;
protected override void Initialize()
{
Host = (DTE2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SDTE));
_extenderProvider = new MyExtenderProvider();
_extenderProviderCookie = Host.ObjectExtenders.RegisterExtenderProvider(VSConstants.CATID.CSharpFileProperties_string,
"MyExtenderProvider", _extenderProvider);
}
protected override void Dispose(bool disposing)
{
Host.ObjectExtenders.UnregisterExtenderProvider(_extenderProviderCookie);
_extenderProvider = null;
base.Dispose(disposing);
}
}
二,。创建实现所需自定义属性的类
三,。创建一个实现自定义属性接口的类
四,。创建实现[IExtenderProvider]接口并重写[GetExtender]和[CanExtend]方法的类
五,。创建从[UITypeEditor]继承并重写[GetEditStyle]和[EditValue]方法的新类
这个答案是可行的,但是这些自定义属性也可以保存在csproj文件中吗?我可以将自定义属性放在旧的csproj格式上。而且,它肯定会在更新的格式上工作。但是,您基本上需要在文件中包含显式元素,以便为存储信息的每个文件存储自定义id属性。我不确定复制、移动、删除和恢复会带来什么意外后果,这可能会带来一些困难的挑战。
[ComVisible(true)] // Important!
public interface IMyDynamicExtender
{
String NewProperty { get; set; }
}
[ComVisible(true)] // Important!
public class NewPropertyExtender : IMyDynamicExtender, IDisposable
{
// These attibutes supply the property with some information
// on how to display and which UITypeEditor to use.
[DisplayName("New Property")]
[Category("New")]
[Description("Specifies the new property")]
[Editor(typeof(CustomUiTypeEditor), typeof(UITypeEditor))]
public String NewProperty { get; set; }
private readonly IExtenderSite _extenderSite;
private readonly int _cookie;
private bool _disposed;
public NewPropertyExtender(IExtenderSite extenderSite, int cookie)
{
_extenderSite = extenderSite;
_cookie = cookie;
}
public void Dispose()
{
Dispose(true);
// take the instance off of the finalization queue.
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing && _cookie != 0)
{
_extenderSite.NotifyDelete(_cookie);
}
_disposed = true;
}
}
public class MyExtenderProvider : IExtenderProvider
{
private IMyDynamicExtender _extender;
public object GetExtender(string extenderCatid, string extenderName,
object extendeeObject, IExtenderSite extenderSite,
int cookie)
{
return _extender = CanExtend(extenderCatid, extenderName, extendeeObject) ?
new NewPropertyExtender(extenderSite, cookie) : null;
}
public bool CanExtend(string extenderCatid, string extenderName, object extendeeObject)
{
// Some implementation will be here in the real world.
return true;
}
}
public class CustomUiTypeEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
// Use the result of a dialog or something else here.
return "HELLO WORLD";
}
}