How to obtain ITypeDescriptorContext and IServiceProvider in inherited ControlDesigner class
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;
精彩评论