如何使用UITypeEditor为Visual Studio创建简单的Automation Extender

时间:2015-09-21 15:43:35

标签: visual-studio ide extensibility

在Visual Studio中,当您在解决方案资源管理器中选择项目或项目项时,有时可能需要将自定义属性添加到属性窗口(按F4时弹出的窗口)。此外,要填写这些属性的值,我需要添加一个按钮来弹出表单,以便我可以在设计时从用户收集信息。

这是最简单的实现,所以我可以开始? 如何通过使用UITypeEditAttribute创建用户界面来收集值?

1 个答案:

答案 0 :(得分:5)

这是我能想到的最简单的实现。

由于这是一个高级主题,因此暗示您在开始实施之前完成所有步骤感觉很舒服(这些都是常见的编程任务)。

如果有任何不够清楚的评论,我会尽量简化。请注意,这配置为在Visual Studio中为Visual C#文件创建自定义属性。当您运行或调试Visual Studio包,然后单击任何.cs文件时,自定义属性应显示在属性窗口中。提供的评论是必需的说明。

enter image description here

  1. 创建Visual Studio包。
  2. 创建一个接口,该接口实现您要添加到属性页面的自定义属性。
  3. 创建一个实现自定义属性接口的类,并使用属性修饰自定义属性。
  4. 创建实施 IExtenderProvider 界面的类,并覆盖 GetExtender CanExtend 方法。
  5. 创建一个继承自 UITypeEditor 的新类,并覆盖 GetEditStyle EditValue 方法。
  6. 让我们开始吧。

    <强> 1。在visual studio中创建包。

    Package.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";
        }
    }