2

I'm developing a Silverlight application, and want to set the ItemsSource of a ListBox to ObeservableCollection<XElement> and still be able to use the Binding Path=Element[name].Value syntax to get values for a data template. I can get the binding successfully, but the Element[] syntax is not working. It just renders empty. For example, this does not work:

<DataTemplate x:Key="SearchResultsTemplate">
    <ListBox ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Path=Element[key].Value}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</DataTemplate>

But oddly, something like this does render content, which tells me everything is bound to some degree, but something is keeping me from using the Element dynamic property:

<DataTemplate x:Key="SearchResultsTemplate">
    <ListBox ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Path=FirstNode}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</DataTemplate>

What am I doing wrong?

decyclone
  • 30,394
  • 6
  • 63
  • 80
Justin Poliey
  • 16,289
  • 7
  • 37
  • 48

2 Answers2

4

The Element pseudoproperty is only available in the desktop version of .NET. It relies on the type descriptor system which is one of the pieces of the .NET Framework that's missing in Silverlight.

In the full .NET framework, XElement has a [TypeDescriptionProvider(typeof(XTypeDescriptionProvider<XElement>))] attribute, which is how those Element and other pseudoproperties are exposed to databinding. This attribute is not present in the Silverlight version of XElement. (And it can't be present because Silverlight doesn't provide a definition of TypeDescriptionProvider, or any of the associated machinery behind that attribute.

Silverlight doesn't provide a direct way to bind to XML content. (It doesn't support XPath either, which is the other solution popular in WPF.) You could look at Binding XML in Silverlight without nominal classes which links to an article by Graham Murray which shows how to generate bindable types dynamically.

That's a relatively complex solution though. I think I'd just write a wrapper type for the XML that includes the data I want, and use LINQ to XML to populate those wrappers from the XML.

Community
  • 1
  • 1
Ian Griffiths
  • 14,302
  • 2
  • 64
  • 88
0

Use XPath instead :

<TextBlock Text="{Binding XPath=<..YourXPathSyntax..>}" />

EDIT:

As Ian pointed out, you are using Silverlight. So, XPath will not work. Why not use IValueConverter instead?

Example :

using System.Xml.Linq;
using System.Xml.XPath;

public class IXPathConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        String xpath = (String)parameter;
        XElement element = (XElement)value;

        return element.Document.XPathSelectElement(xpath);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
decyclone
  • 30,394
  • 6
  • 63
  • 80