如何在继承的ControlDesigner类中获取ITypeDescriptorContext和IServiceProvider

时间:2011-01-26 23:40:33

标签: c# .net winforms user-controls windows-forms-designer

我已将ControlDesigner类继承到MyControlDesigner

在这个类中,我需要获取ITypeDescriptorContextIServiceProvider接口后面的对象,但我不知道如何:(

我需要这两个接口在方法中传递它们,但我无法在任何其他对象中找到它们。

请有人帮助我。

谢谢

祝你好运 博

2 个答案:

答案 0 :(得分:2)

EditorServiceContext程序集中有一个内部类System.Design,它已实现ITypeDescriptorContextIServiceProviderIWindowsFormsEditorService

您可以找到它并创建该类的实例或使用其静态方法来满足您的要求。例如,要显示属性的编辑器,可以这样使用它:

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

如果出于任何原因需要类的源代码对其应用某些更改,则以下是该类的代码:

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

答案 1 :(得分:1)

Component.Site实现了IServiceProvider,关于ITypeDescriptorContext的IDK,我也在寻找它......

要获得IServiceProvider,您可以这样做:var sp =(IServiceProvider)Component.Site;