WPF,在级联ComboBox中将两个XML数据源链接在一起

时间:2010-08-02 21:36:03

标签: c# wpf data-binding combobox datatemplate

我有以下格式的XML:

<Products>
  <Product name="MyProduct1">
    <Components>
      <Component name="MyComponent1">
        <Teams>
          <Team id="1"/>
          <Team id="4"/>
        </Teams>
      </Component>
    </Components>
  </Product>
</Products>

这存储在外部XML文件中,该文件通过我的XAML中的XmlDataProvider包含在内:

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

您会看到Team个节点只有id个属性;这会将它们链接到直接嵌入我的XAML中的其他XML:

<XmlDataProvider x:Key="teamsXml" XPath="Teams/Team">
    <x:XData>
        <Teams xmlns="">
            <Team name="Team A" id="1"/>
            <Team name="Team B" id="2"/>
            <Team name="Team C" id="3"/>
            <Team name="Team D" id="4"/>
        </Teams>
    </x:XData>
</XmlDataProvider>

我的XAML中有以下ComboBox:

<ComboBox Height="23" HorizontalAlignment="Left" Margin="133,217,0,0"
          Name="cbo_team" VerticalAlignment="Top" Width="148"
          DataContext="{Binding ElementName=cbo_component, Path=SelectedItem}"
          ItemsSource="{Binding XPath=Teams/Team}"
          SelectedIndex="0" />

此ComboBox显示与当前所选组件关联的团队列表。我需要在此处保持DataContextItemsSource相同,以便仅显示相关的团队,而不是所有可用的团队。但是,我不想在ComboBox中显示Team id属性,我想显示nameteamsXml定义的DataTemplate属性,例如,团队A.我使用teamsXml并从id获得团队productsXml后以某种方式从name获取团队名称?我还希望ComboBox的值为<ComboBox Height="23" HorizontalAlignment="Left" Margin="133,217,0,0" Name="cbo_team" VerticalAlignment="Top" Width="148" DataContext="{Binding ElementName=cbo_component, Path=SelectedItem}" ItemsSource="{Binding XPath=Teams/Team}" SelectedIndex="0"> <ComboBox.DisplayMemberPath> <Binding Source="{StaticResource teamsXml}" XPath="???"/> <!-- Need to select the @name attribute of the node whose @id attribute is the same value as the current selected item in this ComboBox --> </ComboBox.DisplayMemberPath> </ComboBox> 属性。

修改

我想知道这样的事情是否朝着正确的方向迈出了一步:

{{1}}

2 个答案:

答案 0 :(得分:0)

我将Linq用于xml并填充CollectionViewSource。然后绑定到那个而不是xmlDataProvider。

答案 1 :(得分:0)

再一次,this guy's article帮助了我。我将Teams XML移到了我的Products.xml文件中,所以我有以下格式:

<Products>
  <Product name="MyProduct1">
    <Components>
      <Component name="MyComponent1">
        <Teams>
          <Team id="1"/>
          <Team id="4"/>
        </Teams>
      </Component>
    </Components>
  </Product>
  <Teams>
    <Team name="Team A" id="1"/>
    <Team name="Team B" id="2"/>
    <Team name="Team C" id="3"/>
    <Team name="Team D" id="4"/>
  </Teams>  
</Products>

然后,我在XAML中为我的ComboBox做了以下事情:

<ComboBox Height="23" HorizontalAlignment="Left" Margin="133,218,0,0"
          Name="cbo_team" VerticalAlignment="Top" Width="148"
          DataContext="{Binding ElementName=cbo_component, Path=SelectedItem}">
    <ComboBox.ItemsSource>
        <Binding XPath="Teams/Team/@id"
                 Converter="{StaticResource xmlConverter}">
            <Binding.ConverterParameter>
                <local:XmlConverterParameter
                    XPathTemplate="/Products/Teams/Team[{0}]"
                    XPathCondition="@id='{0}'" />
            </Binding.ConverterParameter>
        </Binding>
    </ComboBox.ItemsSource>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding XPath=@name}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

我必须在XAML的<Window.Resources>中包含以下内容:

<local:XmlConverter x:Key="xmlConverter"/>

在他的教程之后,我创建了两个C#类:XmlConverterXmlConverterParameter。现在我的ComboBox将团队id转换为name并显示name,因此我的XML非常干,因为团队名称只在一个地方定义。