How to obtain ITypeDescriptorContext and IServiceProvider in inherited ControlDesigner class

↘锁芯ラ 提交于 2019-12-07 01:50:12

问题


I have inherited ControlDesigner class into MyControlDesigner.

In this class I need to obtain objects behind ITypeDescriptorContext and IServiceProvider 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


回答1:


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;
        }
    }
}



回答2:


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

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



来源:https://stackoverflow.com/questions/4811446/how-to-obtain-itypedescriptorcontext-and-iserviceprovider-in-inherited-controlde

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!