2016-11-10 89 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',当然没有什么特别的要考虑。 –

相关问题