在 Silverlight 中使用绑定到 XML

发布于 2024-10-17 10:01:12 字数 2863 浏览 1 评论 0原文

我目前在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

毁我热情 2024-10-24 10:01:12

感谢您的回答。

大约两周前,我通过创建一个名为 XTextBox 的新类解决了这个问题。
我简单地从 TextBox 继承,并在新类中创建两个类型为 XElement 和 string 的 DependencyProperties。

在我的 XAML 中,我可以像以前一样使用绑定,并将完整的 XElement 和 XPath 移交给我的控件来找到正确的节点。

<custom:XTextBox Data="{Binding Path=XValues, Mode=TwoWay}" XPath="//Measurements/Headline/Fontsize" />

除了两个 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.

<custom:XTextBox Data="{Binding Path=XValues, Mode=TwoWay}" XPath="//Measurements/Headline/Fontsize" />

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.

顾铮苏瑾 2024-10-24 10:01:12

引用 silverlight 论坛问题 -

“您可以创建一个类来保存数据并实现 INotifyPropertyChanged,然后在代码中读取或写入 xml。

如果 xml 的格式尚未定义,则可以使用“DataContractSerializer”。

写入 xml示例:

  YourDataClassType data = new YourDataClassType();  
  MemoryStream ms = new MemoryStream();
  DataContractSerializer ds = new DataContractSerializer(typeof(YourDataClassType));
  ds.WriteObject(ms, data);
  ms.Flush();
  ms.Seek(0, SeekOrigin.Begin);
  StreamReader sr = new StreamReader(ms);
  string xml = sr.ReadToEnd();
  sr.Close();
  ms.Close();

读取 xml 示例:

MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
sw.Write(xml);
sw.Flush();

ms.Seek(0, SeekOrigin.Begin);

DataContractSerializer ds = new DataContractSerializer(typeof(YourDataClassType));
YourDataClassType data = ds.ReadObject(ms) as YourDataClassType;
sw.Close();
ms.Close();

其中 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 :

  YourDataClassType data = new YourDataClassType();  
  MemoryStream ms = new MemoryStream();
  DataContractSerializer ds = new DataContractSerializer(typeof(YourDataClassType));
  ds.WriteObject(ms, data);
  ms.Flush();
  ms.Seek(0, SeekOrigin.Begin);
  StreamReader sr = new StreamReader(ms);
  string xml = sr.ReadToEnd();
  sr.Close();
  ms.Close();

read xml example :

MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
sw.Write(xml);
sw.Flush();

ms.Seek(0, SeekOrigin.Begin);

DataContractSerializer ds = new DataContractSerializer(typeof(YourDataClassType));
YourDataClassType data = ds.ReadObject(ms) as YourDataClassType;
sw.Close();
ms.Close();

where YourDataClassType is your class that reflects the data. This way you don't have to parse the xml yourself."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文