Binding XML in Silverlight without nominal classes

[亡魂溺海] 提交于 2019-12-03 08:52:09
Graham Murray

You can do this with an IValueConverter. Here is a simple one:

public class XAttributeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var xml = value as XElement;
        var name = parameter as string;
        return xml.Attribute(name).Value;
    }
}

Then in your Xaml you can reference the type converter and pass the attribute name as the parameter:

<ListBox x:Name="ItemList">
    <ListBox.Resources>
        <local:XAttributeConverter x:Name="xcvt" />
    </ListBox.Resources>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Converter={StaticResource xcvt}, ConverterParameter=forename}" />
                <TextBlock Text="{Binding Converter={StaticResource xcvt}, ConverterParameter=surname}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

This is when you bind to the xml loaded in an XElement:

XElement xml = XElement.Parse("<root><item forename='Fred' surname='Flintstone' /><item forename='Barney' surname='Rubble' /></root>");

ItemList.ItemsSource = xml.Descendants("item");

Not a super elegant binding syntax, but it does work and is easier than mapping to classes.

As far as I'm aware the Silverlight Binding lacks the XPath properties found in WPF so there is no nice way to bind directly to XML. When I've encountered this problem I've used xsd.exe against a schema to generate my classes and then use Xml Serialization to populate them. It's not ideal but at least I'm not writing and maintaining the classes and mappings myself.

Could you do something similar to what Bryant is suggesting with a query that uses an anonymous class?

i.e.:

var data = from c in xml.Descendants("item")
                       select new  { Forename = c.Attribute("forename").Value, 
                                     Surname = c.Attribute("surname").Value };
ItemList.ItemsSource = data

I think this should work, but I'm not somewhere I could test it out. If it doesn't, somebody let me know why because now I'm interested.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!