2015-02-11 47 views
0

因此,我有這個通用類型的類,它使用System.Reflection從一個類中獲取所有公共變量並將它們呈現爲控件。C#泛型類型;無法綁定到屬性或列

但是我需要能夠使用這些變量作爲控件的DataBindings,所以當控件接收到輸入時,該輸入保存到相應的變量中。

這是我迄今爲止,但我得到'無法綁定到屬性或列'的錯誤。

的類別:

foreach (var f in type.GetFields().Where(f => f.IsPublic)) 
{ 
    TextBox control = new TextBox(); 
    Binding binding = new Binding("Text", component, f.Name, false, DataSourceUpdateMode.OnPropertyChanged); 
    control.DataBindings.Add(binding); 
} 

回答

0

我想你只能綁定到自定義對象的屬性,而不是字段:

public class ComponentControl<T> where T : Component 
{ 
    private T component; 

    public ComponentControl(T component) 
    { 
     this.component = component; 
    } 
} 

這不會工作的一部分。這似乎有點矯枉過正,但如果有更簡單的方法,我肯定有人會糾正我..

假設你不想改變你的領域的屬性,你真的想要使用綁定,你可以生成一個改用DTO來綁定。例如,這裏是你將如何綁定,所以使用proxyType而不是你的實際類型。

ComponentControl<int> component = new ComponentControl<int>() { A = "A", B = 1, C = 2 }; 
Type type = component.GetType();    
dynamic proxyType = DynamicProxyGenerator.GetInstanceFor<ComponentControl<int>>(component);    

foreach (var f in type.GetFields().Where(f => f.IsPublic)) 
{ 
    TextBox control = new TextBox(); 
    Binding binding = new Binding("Text", proxyType, f.Name, false, DataSourceUpdateMode.OnPropertyChanged); 

    control.DataBindings.Add(binding); 
} 

這裏是產生對於DynamicProxyGenerator代碼..

public static class DynamicProxyGenerator 
{ 
    public static object GetInstanceFor<T>(T toBind) 
    { 
     Type typeOfT = typeof(T); 

     AssemblyName assName = new AssemblyName("testAssembly"); 
     var assBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assName, AssemblyBuilderAccess.RunAndSave);    
     var moduleBuilder = assBuilder.DefineDynamicModule("dynamicModule", "dynamicBinder.dll"); 
     var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "Proxy", TypeAttributes.Public | TypeAttributes.Class);    
     FieldBuilder bindingSourceField = typeBuilder.DefineField("BindingSource", typeOfT, FieldAttributes.Public);    

     foreach (FieldInfo toCopyField in typeOfT.GetFields()) 
     { 
      PropertyBuilder propBuilder = typeBuilder.DefineProperty(toCopyField.Name, System.Reflection.PropertyAttributes.None, toCopyField.FieldType, null);        

      MethodBuilder getter = typeBuilder.DefineMethod("get_" + toCopyField.Name, MethodAttributes.Public, toCopyField.FieldType, Type.EmptyTypes);     
      ILGenerator getIL = getter.GetILGenerator(); 
      getIL.Emit(OpCodes.Ldarg_0); 
      getIL.Emit(OpCodes.Ldfld, bindingSourceField); 
      getIL.Emit(OpCodes.Ldfld, toCopyField); 
      getIL.Emit(OpCodes.Ret); 
      propBuilder.SetGetMethod(getter); 

      MethodBuilder setter = typeBuilder.DefineMethod("set_" + toCopyField.Name, MethodAttributes.Public, null, new Type[] { toCopyField.FieldType }); 
      ILGenerator setIL = setter.GetILGenerator(); 
      setIL.Emit(OpCodes.Ldarg_0); 
      setIL.Emit(OpCodes.Ldfld, bindingSourceField); 
      setIL.Emit(OpCodes.Ldarg_1);     
      setIL.Emit(OpCodes.Stfld, toCopyField); 
      setIL.Emit(OpCodes.Ret); 
      propBuilder.SetSetMethod(setter);     
     } 

     Type constructedType = typeBuilder.CreateType(); 
     dynamic instance = Activator.CreateInstance(constructedType); 
     instance.BindingSource = toBind; 

     return instance; 
    } 
} 

那麼這樣做是動態創建一個新類型,是這樣的,它可以作爲使用綁定源來充當控制和你的對象之間的交流。

public class ComponentControlProxy 
{ 
    public ComponentControl<int> BindingSource; 

    public string A 
    { 
     get 
     { 
      return BindingSource.A; 
     } 
     set 
     { 
      BindingSource.A = value; 
     } 
    } 

    .. etc 
}