2008-12-04 39 views
3

比方说,我有XML的简单chunck: -XML绑定在Silverlight没有标称类

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

有取此XML在Silverlight我想这个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足够简单绑定到XML和标称类: -

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

没有这个课程可以完成吗?

换句话说,Silverlight代码和输入XML之间的耦合仅限于XAML,其他源代码不可知项目元素上的一组属性。

编辑:建议使用XSD,但最终它的数量是相同的。 XSD->生成的类。

编辑:匿名类无效,Silverlight无法绑定它们。

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

回答

0

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

+0

感谢您的回复。 XSD也是我收到的最接近的。我希望有更灵活的东西。 – AnthonyWJones 2008-12-04 16:17:12

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> 

这是当你绑定到一个加载的XML XElement:

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

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

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

+1

这是我最接近的。我很感激你的努力,我对我的可疑提问表示歉意。我遇到的问题是采用这种方法。 (我原来的Q包含TextBlock,我的意思是TextBox)。我需要这是可编辑的。 – AnthonyWJones 2008-12-04 23:10:21

0

你可以做一些类似于科比用一个匿名类查询的建议吗?

即:

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

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

+0

好吧,我发现我肯定有一些根本性的错误,或者这是明显的答案。那么,哪部分不起作用? – MojoFilter 2008-12-04 18:15:58

+0

linq查询的结果不是对象列表,而是{System.Linq.Enumerable.WhereSelectEnumerableIterator f__AnonymousType0 >},我不认为它是可绑定的。尝试一些调整,看看我是否可以使它工作。 – Bryant 2008-12-04 19:21:55