【问题标题】:Dynamically Bind XML to DataGrid in Silverlight在 Silverlight 中将 XML 动态绑定到 DataGrid
【发布时间】:2011-03-14 22:19:52
【问题描述】:

我一直在尝试将 XML(通过 XElement)动态绑定到 Silverlight(特别是 Silverlight 4,但 SL3 中的任何解决方案也可以)中的 DataGrid,但一直无法这样做。我希望动态地做到这一点(即 - 没有严格的业务对象来表示 XML)。

我最终希望的是一种绑定到任何包含任意 XML 的 XElement 的方法,然后使用某种 IConverter 将 XElement 转换为 DataGrid 可以绑定到的东西 - 并且只是“知道”如何从转换后的对象自动生成列和行。

<sdk:DataGrid 
    ItemsSource="{Binding Source={StaticResource MyViewModel}, 
    Path=MyXElement, Converter={SomeConverter}}" AutoGenerateColumns="True">

如果可能,我希望能够利用某种可重用的声明性组件(尽量避免实际视图的代码隐藏)。

我尝试过使用 DynamicObjects,但 DataGrid 无法确定它的属性。

【问题讨论】:

    标签: xml silverlight data-binding datagrid


    【解决方案1】:

    【讨论】:

    • 我希望能够动态计算出数据结构,因为我的 XML 不会显式地按行和列布局结构。
    【解决方案2】:

    以下是另一种可能也有帮助的替代方法。这有点骇人听闻。

    它是使用 Silverlight 3 编写和测试的。

    ViewModel:

    namespace DatagridXml
    {
        public class TestViewModel
        {
            public TestViewModel()
            {
                XmlData = @"<people><person><name>Name1</name><age>21</age><address>Address1</address></person><person><name>Name2</name><age>22</age><address>Address2</address></person><person><name>Name3</name><age>23</age><address>Address3</address></person></people>";
            }
            public string XmlData { get; set; }
        }
    }
    

    价值转换器:

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Xml.Linq;
    
    namespace DatagridXml
    {
        public class XmlColumnConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                string elementToGenerate = parameter.ToString();
                DataGrid control = value as DataGrid;
                control.Columns.Clear();
    
                var result = new List<IList<string>>();
                XDocument xmlDoc = XDocument.Parse(control.DataContext.ToString());
    
                // Generate Columns
                var columnNames = xmlDoc.Descendants(elementToGenerate).FirstOrDefault();
                int pos = 0;
                foreach (var columnName in columnNames.Elements())
                {
                    var column = new DataGridTextColumn();
                    column.Header = columnName.Name;
                    column.Binding = new Binding("[" + pos + "]");
                    control.Columns.Add(column);
                    pos++;
                }
    
                // Parse elements to generate column's data
                foreach (var element in xmlDoc.Descendants(elementToGenerate))
                {
                    var row = new List<string>();
                    foreach (var column in element.Elements())
                    {
                        row.Add(column.Value);
                    }
                    result.Add(row);
                }
                return result;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotSupportedException("Cannot convert to xml from list.");
            }
        }
    }
    

    而且,你可以这样使用:

    <UserControl
        x:Class="DatagridXml.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
        xmlns:local="clr-namespace:DatagridXml"
        mc:Ignorable="d"
        d:DesignWidth="640"
        d:DesignHeight="480">
        <UserControl.Resources>
            <local:XmlColumnConverter
                x:Key="XmlColumnConverter" />
            <local:TestViewModel
                x:Key="TestViewModel" />
        </UserControl.Resources>
        <Grid
            x:Name="LayoutRoot">
            <data:DataGrid
                AutoGenerateColumns="False"
                DataContext="{Binding Source={StaticResource TestViewModel}, Path=XmlData}"
                ItemsSource="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource XmlColumnConverter}, ConverterParameter=person}" />
        </Grid>
    </UserControl>
    

    【讨论】:

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