I'm currently having trouble binding XML to a GUI in a Silverlight application. Especially with TwoWay-Binding.
As we know it is really easy to do in a Windows client application using WPF. There you can just do something like:
XML:
<person>
<firstname>Test</firstname>
<surname>Test</surname>
<email>[email protected]</email>
</person>
and a XAML page viewing a Grid to edit (Binding using either XLinq or XPath):
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="221*" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="First name:" />
<TextBox Grid.Column="1" Grid.Row="0" Text="{Binding Path=Element[firstname].Value, Mode=TwoWay}" />
<TextBlock Grid.Column="0" Grid.Row="1" Text="Surname:" />
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=Element[surname].Value, Mode=TwoWay}" />
<TextBlock Grid.Column="0" Grid.Row="2" Text="EMail:" />
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=Element[email].Value, Mode=TwoWay}" />
</Grid>
Because of the TwoWay-Mode the user writes directly into the XML.
However, in Silverlight there is no option to bind like in the example above. But Microsoft added the XPathEvaluate-Method() in Silverlight 4.
So I was trying to bind the complete XDocument to every TextBox and use a converter along with the ConverterParameter to pass a XPath expression and evaluate it.
<Grid x:Name="LayoutRoot">
<TextBlock Text="{Binding Path=Data, Converter={StaticResource TestKonverter}, ConverterParameter=//firstname, Mode=TwoWay}" FontSize="20" />
</Grid>
and...
public class XMLConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var __doc = (XDocument)value;
var __xpath = (IEnumerable)__doc.XPathEvaluate(parameter.ToString());
return (__xpath.Cast<XElement>().FirstOrDefault());
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//getting the attached XDocument again as __doc ?!
var __xpath = (IEnumerable)__doc.XPathEvaluate(parameter.ToString());
(__xpath.Cast<XElement>().FirstOrDefault()).Value = value.ToString();
return value;
}
}
To get some kind of TwoWay-Binding, I thought of using the XPath-Expression to get the correct Node and write the new value in it. The problem is, in the ConvertBack-Method() I don't see a way how to get the XDocument. Is there any way to get the XDocument through the given parameters in ConvertBack, without making it somewhere as static?