在 Silverlight 中绑定 XML,无需标称类

发布于 2024-07-09 15:06:33 字数 1298 浏览 12 评论 0原文

假设我有一个简单的 XML 块:-

<root>
   <item forename="Fred" surname="Flintstone" />
   <item forename="Barney" surname="Rubble" />
</root>

在 Silverlight 中获取此 XML 后,我想将其与 绑定此类的 XAML:-

<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> 

现在我可以使用 LINQ to XML 和名义类进行足够简单的绑定:-

public class Person {
     public string Forename {get; set;} 
     public string Surname {get; set;}
}

没有此类也能完成吗?

换句话说,Silverlight 代码和输入 XML 之间的耦合仅限于 XAML,其他源代码与 item 元素上的属性集无关。

编辑:建议使用 XSD,但最终效果是一样的。 XSD->生成的类。

编辑:匿名类不起作用,Silverlight 无法绑定它们。

编辑:这需要有两种方式,用户需要能够编辑值,并且这些值最终会出现在 XML 中。 (在上面的示例中将原始 TextBlock 更改为 TextBox。)

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

伴梦长久 2024-07-16 15:06:33

您可以使用 IValueConverter 来完成此操作。 这是一个简单的方法:

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;
    }
}

然后在 Xaml 中,您可以引用类型转换器并将属性名称作为参数传递:

<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>

这是当您绑定到 XElement 中加载的 xml 时:

XElement xml = XElement.Parse("<root><item forename='Fred' surname='Flintstone' /><item forename='Barney' surname='Rubble' /></root>");

ItemList.ItemsSource = xml.Descendants("item");

不是超级优雅的绑定语法,但它确实有效并且比映射到类更容易。

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.

蒲公英的约定 2024-07-16 15:06:33

据我所知,Silverlight Binding 缺少 WPF 中的 XPath 属性,因此没有直接绑定到 XML 的好方法。 当我遇到这个问题时,我针对架构使用 xsd.exe 来生成我的类,然后使用 Xml 序列化来填充它们。 这并不理想,但至少我不是自己编写和维护类和映射。

As far as I'm aware the Silverlight Binding lacks the XPath properties found in WPF so there is no nice way to bind directly to XML. When I've encountered this problem I've used xsd.exe against a schema to generate my classes and then use Xml Serialization to populate them. It's not ideal but at least I'm not writing and maintaining the classes and mappings myself.

浊酒尽余欢 2024-07-16 15:06:33

您能否对使用匿名类的查询执行类似于 Bryant 建议的操作?

即:

var data = from c in xml.Descendants("item")
                       select new  { Forename = c.Attribute("forename").Value, 
                                     Surname = c.Attribute("surname").Value };
ItemList.ItemsSource = data

我认为这应该可行,但我不在可以测试它的地方。 如果没有,有人让我知道原因,因为现在我很感兴趣。

Could you do something similar to what Bryant is suggesting with a query that uses an anonymous class?

i.e.:

var data = from c in xml.Descendants("item")
                       select new  { Forename = c.Attribute("forename").Value, 
                                     Surname = c.Attribute("surname").Value };
ItemList.ItemsSource = data

I think this should work, but I'm not somewhere I could test it out. If it doesn't, somebody let me know why because now I'm interested.

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