2010-08-02 36 views
1

我有以下结构的XML文件:WPF,XML数据绑定到依赖/级联组合框

<Products> 
    <Product name="MyProduct1"> 
    <Components> 
     <Component name="MyComponent1"> 
     <SubComponents> 
      <SubComponent name="MySubComponent1"/> 
      <SubComponent name="MySubComponent2"/> 
      ...more SubComponent nodes... 
     </SubComponents> 
     </Component> 
     ...more Component nodes... 
    </Components> 
    </Product> 
    ...more Product nodes... 
</Products> 

我试图创建一个具有与它的产品名称组合框一个WPF应用程序。我对WPF完全陌生,所以我不知道我是否以正确的方式处理事情。选择产品时,应该使用该产品的所有组件填充第二个组合框。当选择一个组件时,第三个组合框应该填充该组件的所有子组件。

我不知道如何设置组合框之间的依赖关系,除了在由独立组合框触发的事件处理程序中填充依赖组合框之外。这似乎意味着我需要能够读取C#中的XML,所以我有[Serializable]Products,,ComponentSubComponent。不过,我试图做XML数据绑定在我的XAML:

<Window.Resources> 
    <XmlDataProvider Source="Products.xml" 
        XPath="Products/Product" 
        x:Key="productsXml"/> 
</Window.Resources> 

我目前不在我的第一个组合框看到产品名称的列表,其XAML如下:

<ComboBox Height="23" HorizontalAlignment="Left" Margin="138,116,0,0" 
      Name="cbo_product" VerticalAlignment="Top" Width="120" 
      ItemsSource="{Binding Source=productsXml, [email protected]}" 
      SelectionChanged="product_SelectionChanged"/> 

的产品XML应该是只读的 - 用户将无法从应用程序更改XML中的任何值。我只想读取XML数据并将其显示在应用程序中。

我有几个问题:

  1. 我要对这个正确?拥有一个独立的XML文件,我的WPF应用程序可以读取这些文件,其中包含表示XML文件中节点的类,用于从C#中的这些节点提取数据,使用事件处理程序编写ComboBox之间的依赖关系等。
  2. 我的产品名称(例如MyProduct1)是否显示在我的ComboBox中?目前它只显示为空。
  3. 看起来好像有[Serializable]类代表我的XML节点是多余/不必要的,因为XAML已经有了XmlDataProvider/XPath的东西。是这样吗?

编辑:

更新我的组合框的XAML以下,现在我看到在ComboBox我的产品名称的列表,这要归功于decyclone's answer

<ComboBox Height="23" HorizontalAlignment="Left" Margin="138,116,0,0" 
      Name="cbo_product" VerticalAlignment="Top" Width="120" 
      ItemsSource="{Binding Source={StaticResource productsXml}}" 
      DisplayMemberPath="@name" 
      SelectionChanged="product_SelectionChanged"/> 

回答

2

好的,因为我找到了我的more specific question的答案,我想我也知道这个问题的答案。我不需要[Serializable]类,针对不同的节点在我的XML,因为我可以只使用XAML和XPath创建级联/取决于组合框:

<!-- Independent --> 
<ComboBox Height="23" HorizontalAlignment="Left" Margin="138,116,0,0" 
      Name="cbo_product" VerticalAlignment="Top" Width="120" 
      ItemsSource="{Binding Source={StaticResource productsXml}}" 
      DisplayMemberPath="@name"/> 

<!-- Dependent --> 
<ComboBox Height="23" HorizontalAlignment="Left" Margin="138,151,0,0" 
      Name="cbo_component" VerticalAlignment="Top" Width="201" 
      DataContext="{Binding ElementName=cbo_product, Path=SelectedItem}" 
      ItemsSource="{Binding XPath=Components/Component}" 
      DisplayMemberPath="@name"/> 
2

ItemsSource属性应该是设置为将在列表中显示的项目集合,即您的案例中的XmlDataProvider。用户StaticResource定位它,因为它被定义为资源。应该使用DisplayMemberPath属性来选择应该使用哪些属性来显示组合框中的文本。

关于你的第一个(& 3ed)问题,我个人喜欢创建类,而不是使用原始XML。它给我几个好处,如

  • 添加包装属性。例如,FullName = FirstName +“”+ LastName属性。

  • 我不必检查空值和每次我想要访问的值(总是字符串)类型安全。

  • 我可以将自己的行为添加为对于做小任务可能非常有用的方法。

  • 控制序列化方法并使用属性注入自定义逻辑。

问题是,它值得吗?你真的关心这些好处吗?这就像在DataReader和DataSet之间进行选择一样。对于只读和仅显示目的,使用原始XML,如果您打算使用它,请使用类。

+1

这里是如何做到这一点的好例子。 http://msdn.microsoft.com/en-us/library/system.windows.data.xmldataprovider.aspx – decyclone 2010-08-02 14:43:40

+0

这回答了我的问题2)。 :) 谢谢! – 2010-08-02 15:00:13