1

我对这个有点难过。有人有想法么?我将尝试尽可能简短地列出示例。

针对 SQL 2005 数据库创建 Silverlight 3.0 应用程序。使用 RIA 服务和实体框架进行数据访问。

我需要能够根据表格填充网格。但是,我的网格 UI 和我的表格结构是不同的。基本上我的网格需要将行变成列(如 PIVOT 表)。这是我的挑战/假设

  1. 直到运行时我才知道网格上有哪些列。
  2. Silverlight 3 仅支持绑定到属性
  3. Silverlight 3 不允许您向网格中添加一行并手动填充数据。
  4. 众所周知,Silverlight 没有 System.Data(主要是 DataTable)命名空间

那么,如何创建具有动态属性的对象,以便可以绑定到网格。我的每一个想法(多维数组、哈希表等)都分崩离析 b/c SL 需要绑定一个属性,我无法手动添加/填充数据行,我无法弄清楚一种添加动态属性的方法。我看过一篇关于涉及链接列表的解决方案的文章,但我正在寻找更好的选择。它可能归结为制作一个特殊的“Cody Grid”,它将是一堆文本框/标签。肯定可行,但我会失去一些用户期望的网格功能

我能想出的唯一解决方案是在 SQL 2005 中创建一个 PIVOT 表查询并使用基于该查询/视图的实体。SQL 2008 会帮助我解决这个问题。我更愿意在 Silverlight 中执行此操作,但如果这是最后的手段,那就这样吧。如果我走 PIVOT 路线,如何在实体框架中实现不断变化的数据结构?

数据样本。

桌子

姓名 日期 值
Cody 1/1/09 15
Cody 1/2/09 18
Mike 1/1/09 20
Mike 1/8/09 77

网格 UI 应该看起来像

Name       1/1/09       1/2/09     1/3/09 ....   1/8/09
Cody           15         18        NULL          NULL
Mike           20        NULL       NULL           77

科迪

4

3 回答 3

1

我的团队想出了一个很好的解决方案。我不确定谁值得称赞,但它在谷歌土地的某个地方。到目前为止,它工作得很好。

本质上,解决方案归结为使用反射来基于此动态数据构建动态对象。该函数接受一个二维数组并将其转换为具有可以绑定属性的 List 对象。我们将此过程放在 WCF 服务中,它似乎完全符合我们目前的需要。

这是一些使用反射构建对象的代码

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

            string columnName = "whatever";

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

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

                  //The following line is where I’m passing columnName + counter and getting errors with some strings but not others.
                PropertyBuilder exProperty = myType.DefineProperty(columnName + counter.ToString(), 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++;

            }
            finished = myType.CreateType();
于 2009-06-19T15:05:27.043 回答
0

您可以动态设置列及其关联的绑定(确保 AutoGenerateColumns 已关闭):

例如,名称列:

DataGridTextColumn txtColumn = new DataGridTextColumn(); textColumn.Header = "Name"; textColumn.Binding = new Binding("FirstName"); myDataGrid.Columns.Add(txttColumn);

用于存储查询数据的 ObservableCollection 可能会被覆盖以支持旋转,确保更改 DataGrid 列的绑定,如上所示。

注意:我敢肯定,这是相当多的挥手动作(一年多没碰过银光了);但我希望制定另一个策略就足够了。

于 2009-06-12T01:34:12.550 回答
0

如果您使用的是二维数组,那么如上所示动态添加列将不起作用。问题在于 silverlight 它无法理解列与列表的绑定。

因此,我们必须使用行转换器创建行列表,以表示我们的二维数组。

这个对我有用

http://www.scottlogic.co.uk/blog/colin/2010/03/binding-a-silverlight-3-datagrid-to-dynamic-data-via-idictionary-updated/

于 2011-07-12T11:07:53.587 回答