【问题标题】:Silverlight: Binding Dynamic Data to a DataGridSilverlight:将动态数据绑定到 DataGrid
【发布时间】:2011-04-13 19:06:59
【问题描述】:

最近遇到一个问题,希望大家帮忙

我的任务是创建一个可以接受任何数据集的应用程序,并将其显示在一系列网格中(使用类似于选项卡控件的东西)。

我可以在 WPF 中轻松做到这一点: 1.创建一个返回DataSet对象的WCF Service 2. 创建一个带有 DataGrid 的 WPF 窗口 3. 使用 AutoGenerateColumns=True 将 DataSet 的 DataTables 绑定到 WPF DataGrids

现在我被要求在 Silverlight 中执行此操作。所以本质上,我不知道我得到的表会是什么样子,所以我不能创建一个具有可以被扔进集合和绑定的属性的类。 Silverlight 不允许使用数据集。

我觉得这对于任何平台来说都应该是一个相当普遍的需求,有没有一种不需要大量编码来解决限制的方法来处理这个问题?

【问题讨论】:

    标签: silverlight dynamic datagrid binding dataset


    【解决方案1】:

    我个人的回答是不使用 DataSet(我认为它们还是很可怕的);而是让您的 WCF 服务返回业务对象,最好借助一些 ORM 框架(实体框架、NHibernate 等)使其更容易。

    或者您可以使用 Linq to DataSet 在通过 WCF 发送对象之前从 DataSet 创建对象。

    有关详细信息,另请参阅 these threads

    【讨论】:

    • 我真的不需要使用 DataSet——尽管它们很好地绑定到 WPF 控件,这让生活更轻松——但我的挑战是我不知道返回的表集的结构。他们可能有 3 列,或 50。1 行,或数百。当您不知道对象可能是什么时,这使得创建业务对象变得困难。
    • 似乎我两次发布了相同的链接......第二个实际上应该是forums.silverlight.net/forums/p/16309/273785.aspx(现在编辑答案以包含它)这确实暗示了另一种可能性。 (当然,在 Silverlight 中等待数据集支持是没有意义的,今天版本 4 中可能会有更好的解决方案,但这是一个起点)。
    • 好吧,让我们采取另一种方法:完全忘记 DataSet。
    • 糟糕,点击进入帖子(这还为时过早)...如果没有数据集,我将如何提取未知的数据表结构(未知的列、类型和行)并将结果绑定到 Silverlight DataGrid ?
    • 行数未知很容易,您只需返回对象集合而不是单个对象。
    【解决方案2】:

    一种解决方案是将DataSet Column Information 和DataSet XML 传递给silverlight。在 Silverlight 端,使用 System.Reflection.Emit 命名空间提供的函数基于这些数据构建动态数据对象。然后将动态构建的DataObject 的List 绑定到DataGrid。对于 DataSet 中具有相同 DataType 的每一列,动态数据对象将具有一个属性。

    因为我们除了 Data 之外还有 Column Information,绑定到 DataGrid 可以非常灵活。您可以设置 AutoGeneratedColumn = true 以便显示 DataSet 中的所有数据,或者我可以动态生成要显示的列。

    您可以从here下载示例源代码

    【讨论】:

    • 这听起来可行。不幸的是,我的公司阻止了个人数据存储站点,所以现在我无法访问 zip 文件。
    • 对不起,我不能在这里复制源代码。尝试从其他地方下载它。
    • Vinay,虽然我无法验证您的解决方案是否可行,但它让我找到了另一个解决方案,该解决方案可能与此 URL 上的方法相同,也可能不同:blog.bodurov.com/...。我能够成功地对此进行测试。可悲的是,这是很多代码来执行我认为相当基本的功能(将非预定义的数据结构绑定到数据网格)。考虑到在 WPF 中,你可以用大约 4 行易于阅读的代码来处理这个问题,我认为这是 Silverlight 架构中的一个主要漏洞
    【解决方案3】:

    This tutorial 提出了一种看起来比发出动态类简单得多的方法。您基本上利用 Converter 属性绑定到数据行上的索引值。

    我刚刚尝试过这种方法,它似乎效果很好。这是一些代码:

    /// <summary>
    /// Allows us to bind columns to dictionary entries.
    /// </summary>
    public class DictionaryConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var dict = (IDictionary) value;
            return dict[parameter];
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    用法:

    List<IDictionary<string, object>> dicts = GetDictionaryData();
    foreach (var series in _trendChart.Series)
    {
        _dataGrid.Columns.Add(
            new DataGridTextColumn{
                Header = series.Name, 
                Binding = new Binding{
                    Converter = new DictionaryConverter(), 
                    ConverterParameter = series.Name
                }
            });
    }
    _dataGrid.ItemsSource = dicts;
    

    更新

    This article 包含一组更完整的代码,可以添加排序和其他高级功能。

    【讨论】:

      猜你喜欢
      • 2014-10-17
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多