How do you create a simple Automation Extender for

2019-07-15 03:39发布

In Visual Studio when you select project or project items in the solution explorer there are times when you might want to add custom properties to the properties window(the window that pops up when you press F4). Also, to fill in the values of those properties I need to add a button to pop up a form so I can collect information from the user at design time.

What is the simplest implementation of this so I can get started? How would I create a user interface to collect the value some how by using UITypeEditAttribute?

1条回答
SAY GOODBYE
2楼-- · 2019-07-15 04:18

This is the simplest implementation I could come up with.

Since this is an advanced topic, it is implied that you feel comfortable with completing all the steps before you start the implementation(these are all common programming tasks).

If anything is not clear enough just comment and I will try to simplify. Note that this is configured to create a custom property for a Visual C# file within visual studio. When you run or debug your visual studio package followed by clicking any .cs file, the custom property should show in the properties window. The comments provided are required instructions.

enter image description here

  1. Create a Visual Studio package.
  2. Create an interface that implements the custom properties that you would like to add to the properties page.
  3. Create a class that implements the custom property interface and decorate the custom property with attributes.
  4. Create class that implements IExtenderProvider interface and override GetExtender and CanExtend methods.
  5. Create a new class that inherits from UITypeEditor and override GetEditStyle and EditValue methods.

Let's get started.

1. Create Package in 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. Create class that implements your desired custom properties.

[ComVisible(true)] // Important!
public interface IMyDynamicExtender
{
    String NewProperty { get; set; }
}

3. Create a class that implements the custom property interface.

[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. Create class that implements [IExtenderProvider] interface and override [GetExtender] and [CanExtend] methods.

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. Create a new class that inherits from [UITypeEditor] and override [GetEditStyle] and [EditValue] methods.

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";
    }
}
查看更多
登录 后发表回答