2016-11-10 88 views
2

我需要通過向控件添加一個DataSource來將此處理程序附加到RadListView列創建。將未知類型的通用方法事件處理程序附加到

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

我的問題是,我需要進行處理,從這個其他泛型方法附:

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

有問題的行是這一個:

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

因爲BaseEntity是EF基地鍵入所有實體,但這不足以滿足BaseEntity.MemberVisibility方法;這個方法需要知道確切的實體類型來設置基於特定自定義屬性的可見屬性(當然還有網格列)。

問題是:我可以調用base.GenericColumnCreatingHandler,其中T是TipoTabellaBase tipo.Tipo(類型)在設計時不知道類型?

任何幫助將不勝感激! 感謝提前。

丹尼爾

+0

「from this other generic method」 - 'PopulateRecord' is * not * a「generic method」(在C#意義上)。 –

+0

是O.R. Mapper,你是對的。但是,我認爲,這還不是真正的問題... –

回答

1

請注意,這個解決方案是未經測試。

您將不得不在實時運行時實例化base.GenericColumnCreatingHandler<T>的強類型版本。

從你的代碼中,我想你已經知道如何獲得給定方法的MethodInfo instance。您需要獲得MethodInfobase.GenericColumnCreatingHandler<T>(我們稱之爲genericMethodInfo)。

然後,您可以創建方法的強類型版本MakeGenericMethod

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

一旦做到這一點,你需要調用CreateDelegate獲得的東西,你可以分配給ColumnCreating事件,如描述herehere

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

編輯:用this最後代碼示例中代替base。如果特別需要繼承方法,則必須在檢索genericMethodInfo時予以照顧。

+0

您好O. R. Mapper,感謝您的建議。 除了最後一次調用的基本關鍵字之外,它們都看起來不錯。這是新代碼: MethodInfo genericColCreating = base.GetType()。GetMethod(「GenericColumnCreatingHandler」); MethodInfo typedColCreaeting = genericColCreating.MakeGenericMethod(new [] {typeArgs [0]}); lvRecords.ColumnCreating + = (ListViewColumnCreatingEventHandler)typedColCreaeting.CreateDelegate( typeof(ListViewColumnCreatingEventHandler),base); 編譯器說在這種情況下使用基本關鍵字是無效的... –

+0

謝謝O.R. Mapper,我已經將base關鍵字與此切換,並且所有工作都很好! 您拯救了我的一天! 關於stackoverflow的另一個問題:爲什麼我不能給你的迴應+1?我沒有名氣,但我不知道如何實現它! –

+0

@DanielGrandis:哦,對不起,沒有考慮到'base'本身不能這樣使用的情況。但有了這些說法,假設您有意地獲取繼承版本(通過使用'base')而不是當前類中的被覆蓋的版本,那麼您可能不得不小心找到正確的'MethodInfo'。如果實際情況並非如此(你也可以寫'this.GenericColumnCreatingHandler',當然沒有什麼特別的要考慮。 –

相關問題