这是我能想到的最简单的实现。
由于这是一个高级主题,因此意味着您可以在开始实现之前轻松完成所有步骤(这些都是常见的编程任务)。
如果有任何不够清楚的地方,请发表评论,我会尽力简化。请注意,这配置为在 Visual Studio 中为 Visual C# 文件创建自定义属性。当您运行或调试 Visual Studio 包并单击任何 .cs 文件时,自定义属性应显示在属性窗口中。提供的评论是必需的说明。
- 创建 Visual Studio 包。
- 创建一个接口来实现您想要添加到属性页的自定义属性。
- 创建一个实现自定义属性接口的类,并使用属性来装饰自定义属性。
- 创建实现的类扩展提供者接口和覆盖获取扩展器 and 可以扩展方法。
- 创建一个新类,继承自UI类型编辑器并覆盖获取编辑样式 and 编辑值方法。
让我们开始吧。
1. 在 Visual Studio 中创建包。
包.cs
// ...
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);
}
}
2. 创建实现您所需的自定义属性的类。
[ComVisible(true)] // Important!
public interface IMyDynamicExtender
{
String NewProperty { get; set; }
}
3. 创建一个实现自定义属性接口的类。
[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;
}
}
4. 创建实现 [IExtenderProvider] 接口的类并重写 [GetExtender] 和 [CanExtend] 方法。
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;
}
}
5. 创建一个继承[UITypeEditor]的新类并重写[GetEditStyle]和[EditValue]方法。
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";
}
}