在 Silverlight 中使用绑定到 XML
我目前在 Silverlight 应用程序中将 XML 绑定到 GUI 时遇到问题。特别是双向绑定。
我们知道,在使用 WPF 的 Windows 客户端应用程序中实现这一点非常容易。 在那里,您可以执行以下操作:
XML:
<person>
<firstname>Test</firstname>
<surname>Test</surname>
<email>[email protected]</email>
</person>
和查看要编辑的网格的 XAML 页面(使用 XLinq 或 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>
由于 TwoWay 模式,用户直接写入 XML。
但是,在 Silverlight 中,没有像上面示例中那样进行绑定的选项。但是 Microsoft 在 Silverlight 4 中添加了 XPathEvaluate-Method()。
因此,我尝试将完整的 XDocument 绑定到每个 TextBox,并使用转换器和 ConverterParameter 来传递 XPath 表达式并对其求值。
<Grid x:Name="LayoutRoot">
<TextBlock Text="{Binding Path=Data, Converter={StaticResource TestKonverter}, ConverterParameter=//firstname, Mode=TwoWay}" FontSize="20" />
</Grid>
并且...
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;
}
}
为了获得某种双向绑定,我想到使用 XPath 表达式来获取正确的节点并在其中写入新值。 问题是,在 ConvertBack-Method() 中我没有看到如何获取 XDocument 的方法。有没有办法通过 ConvertBack 中的给定参数获取 XDocument,而不将其设置为静态?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
感谢您的回答。
大约两周前,我通过创建一个名为 XTextBox 的新类解决了这个问题。
我简单地从 TextBox 继承,并在新类中创建两个类型为 XElement 和 string 的 DependencyProperties。
在我的 XAML 中,我可以像以前一样使用绑定,并将完整的 XElement 和 XPath 移交给我的控件来找到正确的节点。
除了两个 DependencyProperties 之外,我还使用普通的 TextChanged 事件再次使用 XPath 更新 XElement 中的值。
这完全解决了双向绑定,因为我永远不需要创建一个新的 XElement 并复制周围的任何内容。我还实现了 XComboBox、XRadioButton 和 XCheckBox,这对我来说就足够了。
Thanks for your answer.
About two weeks ago I solved this problem, by just creating a new class called XTextBox.
I simple inherit from TextBox and create two DependencyProperties with the types XElement and string in the new class.
In my XAML I can use binding as i did before and hand over the complete XElement and the XPath to find the right node to my control.
Aside from the two DependencyProperties I use a normal TextChanged Event to update the Value in the XElement using the XPath again.
This completley solves TwoWay Binding, because I never have to create a new XElement and copy anything around. I also implemented XComboBox, XRadioButton and XCheckBox, which is enough in my case.
引用 silverlight 论坛问题 -
“您可以创建一个类来保存数据并实现 INotifyPropertyChanged,然后在代码中读取或写入 xml。
如果 xml 的格式尚未定义,则可以使用“DataContractSerializer”。
写入 xml示例:
读取 xml 示例:
其中 YourDataClassType 是反映数据的类,这样您就不必自己解析 xml。”
quote from a silverlight forum question -
"You can create a class to hold your data and implement INotifyPropertyChanged and then read or write your xml in code.
If the format of your xml is not already defined, you can use 'DataContractSerializer'.
write xml example :
read xml example :
where YourDataClassType is your class that reflects the data. This way you don't have to parse the xml yourself."