2011-01-26 12 views
5

Ho ereditato la classe ControlDesigner in MyControlDesigner.Come ottenere ITypeDescriptorContext e IServiceProvider nella classe ControlDesigner ereditata

In questa classe ho bisogno di ottenere oggetti dietro ITypeDescriptorContext e IServiceProvider interfacce, ma io non so come :(

Ho bisogno di questi 2 interfacce di passarli nel metodo, ma non riesco a trovare al loro interno qualsiasi altro oggetto.

qualcuno può per favore mi aiuti.

Thank you

migliori saluti Bojan

.210
+0

si tratta di una vecchia questione e, probabilmente, non si ha più bisogno di una risposta, ma i lettori futuri può trovare [la mia risposta] (http://stackoverflow.com/questions/4811446/how-to- get-itypedescriptorcontext-and-iserviceprovider-in-inherited-controlde # 43827054) sotto utile. –

risposta

1

Component.Site implementa IServiceProvider, IDK su ITypeDescriptorContext, sto cercando troppo ...

Per ottenere IServiceProvider si può fare: var = sp (IServiceProvider) Component.Site;

+0

Grazie per la risposta, funziona. Continuerò a cercare ITypeDescriptorContext. Se lo trovo, lo scriverò qui. Grazie ancora. – Bojan

+0

Felice di essere d'aiuto :) – VoidMain

+0

È una vecchia domanda e probabilmente non hai più bisogno della risposta, ma i futuri lettori potrebbero trovare [la mia risposta] (http://stackoverflow.com/questions/4811446/how-to-to get-itypedescriptorcontext-and-iserviceprovider-in-inherited-controlde # 43827054) sotto utile. –

2

C'è una classe interna EditorServiceContext in System.Design complesso che ha attuato ITypeDescriptorContext, IServiceProvider e IWindowsFormsEditorService.

Puoi trovarlo e creare un'istanza della classe o utilizzare i suoi metodi statici per soddisfare le tue esigenze. Per esempio per mostrare l'editor per una proprietà, è possibile utilizzare in questo modo:

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

Se per qualsiasi motivo è necessario l'origine della classe da applicare alcune modifiche ad esso, ecco il codice per quella classe:

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

Ho testato la classe per [questo esempio] (http://stackoverflow.com/a/43826903/3110834). Inoltre ho implementato una versione più leggera per [questo] (http://stackoverflow.com/a/36794920/3110834) e [questo] (http://stackoverflow.com/a/36314635/3110834). –

Problemi correlati