Let's say I have a simple chunck of XML:-
<root>
<item forename="Fred" surname="Flintstone" />
<item forename="Barney" surname="Rubble" />
</root>
Having fetched this XML in Silverlight I would like to bind it with XAML of this ilke:-
<ListBox x:Name="ItemList" Style="{StaticResource Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Forename}" />
<TextBox Text="{Binding Surname}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Now I can bind simply enough with LINQ to XML and a nominal class:-
public class Person {
public string Forename {get; set;}
public string Surname {get; set;}
}
Can it be done without this class?
In other words, coupling between the Silverlight code and the input XML is limited to the XAML only, other source code is agnostic to the set of attributes on the item element.
Edit: The use of XSD is suggested but ultimately it amounts the same thing. XSD->Generated class.
Edit: An anonymous class doesn't work, Silverlight can't bind them.
Edit: This needs to be two way, the user needs to be able to edit the values and these values end up in the XML. (Changed original TextBlock to TextBox in sample above.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With