在 Silverlight 中将 XML 动态绑定到 DataGrid [英] Dynamically Bind XML to DataGrid in Silverlight

查看:17
本文介绍了在 Silverlight 中将 XML 动态绑定到 DataGrid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've been trying to bind XML (via an XElement) to a DataGrid dynamically in Silverlight (specifically Silverlight 4, but any solutions in SL3 would be fine too) but have been unable to do so. I hope to do this dynamically (ie - no rigid business objects to represent the XML).

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

What I'm hoping for in the end is a way to bind to any XElement containing arbitrary XML, and then use some sort of IConverter to transform the XElement into something the DataGrid can bind to - and just "know" how to auto-generate columns and rows from the converted object.

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

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

If possible, I'd like to be able to utilize some sort of reusable declarative component (trying to avoid code-behind on actual Views).

我尝试过使用 DynamicObjects,但 DataGrid 无法确定其属性.

I've tried using DynamicObjects, but the DataGrid can't figure out its properties.

推荐答案

下面是另一种可能也有帮助的替代方案.这有点像黑客.

Below is another alternative that may also help. It's a bit of a hack.

视图模型:

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>

这篇关于在 Silverlight 中将 XML 动态绑定到 DataGrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆