2016-11-10 7 views
2

Ich muss diesen Handler an eine RadListView-Spaltenerstellung anhängen, indem Sie dem Steuerelement eine DataSource hinzufügen.Anfügen Generische Methode Ereignishandler mit unbekanntem Typ

public void GenericColumnCreatingHandler<T>(object sender, ListViewColumnCreatingEventArgs e) 
    { 
     e.Column.Visible = BaseEntity<int>.MemberVisibility<T> 
      (e.Column.FieldName, TelerikPropertyVisibilityAttribute.VisibilityTypeEnum.BaseDetails); 

     e.Column.HeaderText = CaricaTestoLocale(e.Column.HeaderText, "Col_" + e.Column.HeaderText);       

     e.Column.BestFit(); 
     e.Column.AutoSizeMode = ListViewBestFitColumnMode.AllCells; 
    } 

Mein Problem ist, dass ich der Handler anhängen aus dieser anderen generischen Verfahren durchführen müssen:

private void PopulateRecord(TipoTabellaBase tipo) 
    { 
     Type generic = typeof(CommonTableService<>); 
     Type[] typeArgs = { tipo.Tipo }; 
     var constructed = generic.MakeGenericType(typeArgs); 

     var instance = Activator.CreateInstance(constructed); 
     if (instance == null) 
      return; 

     MethodInfo getEntities = constructed.GetMethod("GetEntitiesWithNoParameters"); 
     //getEntities = getEntities.MakeGenericMethod(typeArgs);    

     var result = (IEnumerable<BaseEntity<int>>)getEntities.Invoke(instance, null);                     
     lvRecords.ColumnCreating += base.GenericColumnCreatingHandler<BaseEntity<int>>; 
     lvRecords.DataSource = result; 
     BestFit(lvRecords); 

     generic = null; 
     typeArgs = null; 
     constructed = null; 
     getEntities = null; 
     instance = null;   
    } 

Die problematische Zeile ist diese:

lvRecords.ColumnCreating += base.GenericColumnCreatingHandler<BaseEntity<int>> 

weil BaseEntity EF Basis Typ für alle Entitäten, aber dies ist nicht genug für die BaseEntity.MemberVisibility-Methode; Diese Methode muss den genauen Entitätstyp kennen, um die sichtbaren Eigenschaften (und natürlich die Rasterspalte) basierend auf einem bestimmten benutzerdefinierten Attribut festzulegen.

Frage ist: wie kann ich base.GenericColumnCreatingHandler wo T ist TipoTabellaBase tipo.Tipo (Typ) ohne zu wissen, Typ zur Entwurfszeit?

Jede Hilfe wäre sehr willkommen! Danke ist Fortschritt.

Daniel

+0

"von dieser anderen generischen Methode" - 'PopulateRecord' ist * nicht * eine" generische Methode "(im C# Sinn). –

+0

Ja O.R. Mapper, du hast Recht. Aber ich denke, das ist noch nicht das eigentliche Problem ... –

Antwort

1

Bitte beachten Sie, dass diese Lösung nicht getestet ist.

Sie müssen die stark typisierte Version von base.GenericColumnCreatingHandler<T> zur Laufzeit instanziieren.

Aus Ihrem Code, ich weiß, Sie wissen bereits, wie Sie eine MethodInfo instance für eine bestimmte Methode erhalten. Sie müssen die MethodInfo für base.GenericColumnCreatingHandler<T> (nennen wir es genericMethodInfo) bekommen.

MethodInfo typedMethodInfo = genericMethodInfo.MakeGenericMethod(new[] { 
           typeof(BaseEntity<int>) 
          }); 

Sobald dies geschehen ist, müssen Sie CreateDelegate aufrufen, etwas zu erhalten, die Sie dem ColumnCreating Ereignis zuordnen können, wie:

Dann können Sie eine stark typisierte Version dieser Methode mit MakeGenericMethod erstellen beschrieben here oder here:

lvRecords.ColumnCreating += 
    (ListViewColumnCreatingEventHandler)typedMethodInfo.CreateDelegate(
     typeof(ListViewColumnCreatingEventHandler), this); 

EDIT: base mit this im letzten Codebeispiel ersetzt wird. Falls eine vererbte Methode speziell benötigt wird, muss dies beim Abrufen von genericMethodInfo erledigt werden.

+0

Hallo O. R. Mapper, danke für deinen Vorschlag. Alle scheinen gut, mit Ausnahme der Basis-Schlüsselwort beim letzten Anruf. Dies ist der neue Code: MethodInfo genericColCreating = base.GetType(). GetMethod ("GenericColumnCreatingHandler"); MethodInfo typedColCreaeting = genericColCreating.MakeGenericMethod (neu [] {typeArgs [0]}); lvRecords.ColumnCreating + = (ListViewColumnCreatingEventHandler) typedColCreaeting.CreateDelegate ( typeof (ListViewColumnCreatingEventHandler), Basis); Compiler sagt, dass die Verwendung von Basis-Schlüsselwort in diesem Kontext nicht gültig ist ... –

+0

Dank O.R. Mapper, ich habe Base-Keyword mit diesem und allen funktioniert gut! Sie sparen meinen Tag! Eine weitere Frage zu stackoverflow: Warum kann ich Ihrer Antwort nicht +1 geben? Ich habe keinen guten Ruf, aber ich weiß nicht, wie ich das erreichen kann !!! –

+0

@DanielGrandis: Oh, Entschuldigung, habe nicht den Fall berücksichtigt, dass "Base" allein nicht so verwendet werden kann. Aber damit müssen Sie möglicherweise darauf achten, dass Sie die richtige "MethodInfo" zu Beginn finden, da Sie absichtlich die geerbte Version (durch die Verwendung von "base") statt einer überschriebenen in der aktuellen Klasse abrufen. Wenn das nicht wirklich der Fall ist (und Sie hätten 'this.GenericColumnCreatingHandler' auch schreiben können, dann muss natürlich nichts besonderes berücksichtigt werden. –

Verwandte Themen