开发者

How to obtain ITypeDescriptorContext and IServiceProvider in inherited ControlDesigner class

开发者 https://www.devze.com 2023-02-07 10:46 出处:网络
I have inherited ControlDesigner class into MyControlDesigner. In this class I need to obtain objects behind ITypeDescriptorContext and IServiceProvid开发者_如何学Cer interfaces, but I don\'t know ho

I have inherited ControlDesigner class into MyControlDesigner.

In this class I need to obtain objects behind ITypeDescriptorContext and IServiceProvid开发者_如何学Cer interfaces, but I don't know how :(

I need these 2 interfaces to pass them in method, but I can't find them inside any other object.

Can somebody please help me.

Thank you

Best regards Bojan


There is an internal class EditorServiceContext in System.Design assembly which has implemented ITypeDescriptorContext, IServiceProvider and IWindowsFormsEditorService.

You can find it and create an instance of the class or use its static methods to satisfy your requirement. For example to show the editor for a property, you can use it this way:

var editorServiceContext = typeof(ControlDesigner).Assembly.GetTypes()
    .Where(x => x.Name == "EditorServiceContext").FirstOrDefault();
var editValue = editorServiceContext.GetMethod("EditValue",
    System.Reflection.BindingFlags.Static |
    System.Reflection.BindingFlags.Public);
editValue.Invoke(null, new object[] { this, this.Component, "The Property Name" });

If for any reason you need the source of the class to apply some changes to it, here is the code for that class:

using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

internal class EditorServiceContext : 
    IWindowsFormsEditorService, ITypeDescriptorContext, IServiceProvider
{
    // Fields
    private IComponentChangeService _componentChangeSvc;
    private ComponentDesigner _designer;
    private PropertyDescriptor _targetProperty;

    // Methods
    internal EditorServiceContext(ComponentDesigner designer)
    {
        this._designer = designer;
    }

    internal EditorServiceContext(ComponentDesigner designer, PropertyDescriptor prop)
    {
        this._designer = designer;
        this._targetProperty = prop;
        if (prop == null)
        {
            prop = TypeDescriptor.GetDefaultProperty(designer.Component);
            if ((prop != null) && typeof(ICollection).IsAssignableFrom(prop.PropertyType))
            {
                this._targetProperty = prop;
            }
        }
    }

    internal EditorServiceContext(ComponentDesigner designer, PropertyDescriptor prop, string newVerbText) : this(designer, prop)
    {
        this._designer.Verbs.Add(new DesignerVerb(newVerbText, new EventHandler(this.OnEditItems)));
    }

    public static object EditValue(ComponentDesigner designer, object objectToChange, string propName)
    {
        PropertyDescriptor prop = TypeDescriptor.GetProperties(objectToChange)[propName];
        EditorServiceContext context = new EditorServiceContext(designer, prop);
        object obj2 = prop.GetValue(objectToChange);
        object obj3 = (prop.GetEditor(typeof(UITypeEditor)) as UITypeEditor).EditValue(context, context, obj2);
        if (obj3 != obj2)
        {
            try
            {
                prop.SetValue(objectToChange, obj3);
            }
            catch (CheckoutException)
            {
            }
        }
        return obj3;
    }

    private void OnEditItems(object sender, EventArgs e)
    {
        object component = this._targetProperty.GetValue(this._designer.Component);
        if (component != null)
        {
            CollectionEditor editor = TypeDescriptor.GetEditor(component, typeof(UITypeEditor)) as CollectionEditor;
            if (editor != null)
            {
                editor.EditValue(this, this, component);
            }
        }
    }

    void ITypeDescriptorContext.OnComponentChanged()
    {
        this.ChangeService.OnComponentChanged(this._designer.Component, this._targetProperty, null, null);
    }

    bool ITypeDescriptorContext.OnComponentChanging()
    {
        try
        {
            this.ChangeService.OnComponentChanging(this._designer.Component, this._targetProperty);
        }
        catch (CheckoutException exception1)
        {
            if (exception1 != CheckoutException.Canceled)
            {
                throw;
            }
            return false;
        }
        return true;
    }

    object IServiceProvider.GetService(Type serviceType)
    {
        if ((serviceType == typeof(ITypeDescriptorContext)) || (serviceType == typeof(IWindowsFormsEditorService)))
        {
            return this;
        }
        if ((this._designer.Component != null) && (this._designer.Component.Site != null))
        {
            return this._designer.Component.Site.GetService(serviceType);
        }
        return null;
    }

    void IWindowsFormsEditorService.CloseDropDown()
    {
    }

    void IWindowsFormsEditorService.DropDownControl(Control control)
    {
    }

    DialogResult IWindowsFormsEditorService.ShowDialog(Form dialog)
    {
        IUIService service = (IUIService)((IServiceProvider)this).GetService(typeof(IUIService));
        if (service != null)
        {
            return service.ShowDialog(dialog);
        }
        return dialog.ShowDialog(this._designer.Component as IWin32Window);
    }

    // Properties
    private IComponentChangeService ChangeService
    {
        get
        {
            if (this._componentChangeSvc == null)
            {
                this._componentChangeSvc = (IComponentChangeService)((IServiceProvider)this).GetService(typeof(IComponentChangeService));
            }
            return this._componentChangeSvc;
        }
    }

    IContainer ITypeDescriptorContext.Container
    {
        get
        {
            if (this._designer.Component.Site != null)
            {
                return this._designer.Component.Site.Container;
            }
            return null;
        }
    }

    object ITypeDescriptorContext.Instance
    {
        get
        {
            return this._designer.Component;
        }
    }

    PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor
    {
        get
        {
            return this._targetProperty;
        }
    }
}


Component.Site implements IServiceProvider, IDK about ITypeDescriptorContext, i'm looking for it too...

To get IServiceProvider you can do: var sp = (IServiceProvider)Component.Site;

0

精彩评论

暂无评论...
验证码 换一张
取 消