在Silverlight中绑定XML而不使用名义类

时间:2008-12-04 13:55:01

标签: c# xml silverlight linq-to-xml xml-binding

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

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

在Silverlight中获取此XML后,我想将其与此ilke的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-&gt;生成的类。

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

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

4 个答案:

答案 0 :(得分:3)

您可以使用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");

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

答案 1 :(得分:2)

有关信息,请参阅 Binding to Anonymous types in Silverlight

答案 2 :(得分:0)

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

答案 3 :(得分:0)

你可以做一些类似于Bryant建议使用匿名类的查询吗?

即:

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

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