2011-01-26 8 views
5

Odziedziczyłem klasę ControlDesigner w MyControlDesigner.Jak uzyskać ITypeDescriptorContext i IServiceProvider w odziedziczonej klasie ControlDesigner

W tej klasie muszę uzyskać obiektów za ITypeDescriptorContext i IServiceProvider interfejsów, ale nie wiem jak :(

muszę te 2 interfejsy przekazać je w sposób, ale nie mogę ich znaleźć wewnątrz każdy inny przedmiot.

Czy ktoś mógłby mi pomóc.

Dziękuję

poważaniem Bojan

+0

To stara sprawa i chyba nie trzeba już odpowiedź, ale przyszli czytelnicy mogą znaleźć [moja odpowiedź] (http://stackoverflow.com/questions/4811446/how-to- get-itypedescriptorcontext-and -servservrovider-in -herherher-controlde # 43827054) poniżej przydatne. –

Odpowiedz

1

Component.Site realizuje IServiceProvider, IDK o ITypeDescriptorContext, szukam dla niego zbyt ...

Aby uzyskać IServiceProvider można zrobić: var sp = (IServiceProvider) Component.Site;

+0

Dziękuję za odpowiedź, działa. Będę nadal szukał ITypeDescriptorContext. Jeśli to znajdę, napiszę to tutaj. Dzięki jeszcze raz. – Bojan

+0

Cieszę się, że pomogę :) – VoidMain

+0

To stare pytanie i prawdopodobnie nie potrzebujesz już odpowiedzi, ale przyszli czytelnicy mogą znaleźć [moją odpowiedź] (http://stackoverflow.com/questions/4811446/how-to- get-itypedescriptorcontext-and -servservrovider-in -herherher-controlde # 43827054) poniżej przydatne. –

2

Istnieje klasa wewnętrzna EditorServiceContext w System.Design zespołu, który wdrożył ITypeDescriptorContext, IServiceProvider i IWindowsFormsEditorService.

Możesz go znaleźć i utworzyć instancję klasy lub użyć jej statycznych metod, aby spełnić swoje wymagania. Na przykład, aby pokazać edytor właściwości, można użyć go w ten sposób:

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

Jeśli z jakiegoś powodu musisz źródło klasy zastosować pewne zmiany do niej, tutaj jest kod że klasa:

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

Testowałem klasy dla [tego przykładu] (http://stackoverflow.com/a/43826903/3110834). Wprowadziłem także lżejszą wersję dla [this one] (http://stackoverflow.com/a/36794920/3110834) i [this one] (http://stackoverflow.com/a/36314635/3110834). –

Powiązane problemy