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 be
Below is another alternative that may also help. It's a bit of a hack.
It's written and tested using Silverlight 3.The 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; }
}
}
The value converter:
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.");
}
}
}
And, you use like this:
<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>
Take a look on the following link. It may be a good start: http://www.scottlogic.co.uk/blog/colin/2010/03/binding-a-silverlight-3-datagrid-to-dynamic-data-via-idictionary-updated/