none
请问Silverlight 如何绑定Dictionary(System.Reflection高手请进!) RRS feed

  • 问题

  • 请问Silverlight 如何绑定Dictionary
    如要实现这个东西,怎么办:
    var Ds = new Dictionary();
    Ds.Add("StuName","LiaoSC");
    Ds.Add("StuAge","24");
    GrdRoot.DataContext = Ds  //???????????,因为SL只能绑定属性,而Ds无属性。
    TxtName.Content.SetBinding(new Binding("StuName")); //???????????
    -----------------------
    思路:想将Dictionary对象通过反射,形成有属性的实体,然后将这个实体赋予GrdRoot的DataContext中,就可解决。
    问题是怎么样动态产生一个有属性的强类型实体?千万不要告诉我,手动创建一个实体类。我需要的是根据Dictionary对象自动创建能够用于数据绑定数据源(DataContext)的实体。
    -----------------------
    我已经通过反射把Dictionary的Key动态转换成了属性,但是不知道为什么还是绑定不了。
    --------------------
    比如:我的Dictionay对象如下:
    Ds.Add("StuName","LiaoSC")
    Ds.Add("StuAge,240);
    通过反射形成:(不是手动写代码,是反射生成的,类似的代码,不要以为真)
    Public Class CStudent{
        Public String StuName {Get; Set}
        Public Int32 StuAge {Get; Set }
    }

    ---------------
    然后:
    Var Student = New CStudent;
    Student.StuName="LiaoSC";
    Student.StuAge=10;

    GrdRoot.DataContext = Student

    这样就达到了动态绑定Dictionary.
    ----------------
    实际上,就是要把Dictionary中的Key转换为属性,这样就可绑定。
    目前,我通过反射已经将Dictionary的Key转换成了属性,但是,似乎SL不认我转换出来的结果。气死我了!!!!!!!!!
    当然,你们如果不搞通用程序,你们是没有这种需求的。我是作通用程序,所以对有这种需求。
    但是没有作成功,我要的是动态绑定,不是实现知道所有的属性,要根据Dictionary对象中的Key来生成属性,再绑定到有关SL的控件上。
    ---------------



    但是我还没有搞定。请高手帮忙。
    • 已编辑 TFSoft 2009年8月24日 6:58
    2009年8月24日 6:08

答案

全部回复

  • TFSoft 自己已经搞定。算了毛主席告诉我们“自力更生,艰苦奋斗”
    2009年8月24日 7:27
  • 晕  自问自答
    2009年8月24日 7:36
  • 我正在把那个东西做成通用的东西。其实.net程序有点难度的或者技术含量的,就是那个System.Reflection了,其他的类,大家基本看看就明白。
    2009年8月24日 15:27
  • 你好,
    请参考:
    http://silverlight.net/forums/p/72574/174914.aspx#174914
    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Need a sample of a technique of Microsoft? Just check out CodeFx first! http://cfx.codeplex.com/
    2009年8月25日 9:43
    版主
  • 我已经书写了一个通用的转换的工具,TFDataSource,解决这个我难题。并且已经贴出。
    2009年8月25日 10:15
  • 楼主能否讲讲是如何实现的 谢谢谢谢...
    2013年1月15日 6:37
  • 你好,

    我原来的帖失效了.这里再贴下代码.

     

    xaml.cs:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Net;

    using System.Windows;

    using System.Windows.Controls;

    using System.Windows.Documents;

    using System.Windows.Input;

    using System.Windows.Media;

    using System.Windows.Media.Animation;

    using System.Windows.Shapes;

    using System.Reflection.Emit;

    using System.Reflection;

    namespace SilverlightApplication1

    {

    public partial class Page : UserControl

    {

    public Page()

    {

    InitializeComponent();

    this.Loaded += new RoutedEventHandler(Page_Loaded);

    }

    static Random r = new Random();

    void Page_Loaded(object sender, RoutedEventArgs e)

    {

    //init array

    int[,] array = new int[5, 7];

    for (int i = 0; i < 5; i++)

    {

    for (int j = 0; j < 7; j++)

    {

    array[i, j] = r.Next(1, 100);

    }

    }

    this.DataGrid1.ItemsSource = new DataSource_TwoDimensionArray<int>(array);

    }

    }

    public class DataSource_TwoDimensionArray<T> : List<object> where T : new()

    {

    private Type finished;

    private int counter=0;

    private void Emit(T[,] array)

    {

    AppDomain myDomain = AppDomain.CurrentDomain;

    AssemblyName myAsmName = new AssemblyName("MyAssembly");

    AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);

    ModuleBuilder myModule = myAssembly.DefineDynamicModule(myAsmName.Name);

    TypeBuilder myType = myModule.DefineType("DataSource", TypeAttributes.Public);


    for (int j = 0; j <= array.GetUpperBound(1); j++)

    {

    Type properyType = typeof(T);

    FieldBuilder exField = myType.DefineField("_" + "columnName" + counter, properyType, FieldAttributes.Private);

    PropertyBuilder exProperty = myType.DefineProperty("columnName" + counter, PropertyAttributes.None, properyType, Type.EmptyTypes);

    //Get

    MethodBuilder exGetMethod = myType.DefineMethod("get_" + "columnName"+counter, MethodAttributes.Public, properyType, Type.EmptyTypes);

    ILGenerator getIlgen = exGetMethod.GetILGenerator();

    //IL for a simple getter:

    //ldarg.0

    //ldfld int32 SilverlightClassLibrary1.Class1::_Age

    //ret

    getIlgen.Emit(OpCodes.Ldarg_0);

    getIlgen.Emit(OpCodes.Ldfld, exField);

    getIlgen.Emit(OpCodes.Ret);

    exProperty.SetGetMethod(exGetMethod);

    //Set

    MethodBuilder exSetMethod = myType.DefineMethod("set_" + "columnName" + counter, MethodAttributes.Public, null, new Type[] { properyType });

    ILGenerator setIlgen = exSetMethod.GetILGenerator();

    //IL for a simple setter:

    //ldarg.0

    //ldarg.1

    //stfld int32 SilverlightClassLibrary1.Class1::_Age

    //ret

    setIlgen.Emit(OpCodes.Ldarg_0);

    setIlgen.Emit(OpCodes.Ldarg_1);

    setIlgen.Emit(OpCodes.Stfld, exField);

    setIlgen.Emit(OpCodes.Ret);

    exProperty.SetSetMethod(exSetMethod);

    //counter++

    counter++;


    }


    finished = myType.CreateType();


    }


    public DataSource_TwoDimensionArray(T[,] array)

    {

    Emit(array);

    AddPrivate(array);

    }

    private void AddPrivate(T[,] array)

    {


    int _count = 0;

    for (int i = 0; i<= array.GetUpperBound(0); i++)

    {


    object item = Activator.CreateInstance(finished);

    for (int j = 0; j <= array.GetUpperBound(1); j++)

    {

    string propertyname = "columnName" + _count;

    MethodInfo method = finished.GetMethod("set_" + propertyname);

    method.Invoke(item, new object[] { array[i,j] });

    _count++;

    }

    _count = 0;

    base.Add(item);

    }


    }


    }

    }

    xaml:

    <data:DataGrid x:Name="DataGrid1"></data:DataGrid>


    Allen Chen
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月15日 7:56
    版主