WPF,将级联组合框中的两个 XML 数据源链接在一起
我有以下格式的 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 显示与当前所选组件关联的团队列表。我需要在此处保持 DataContext
和 ItemsSource
相同,以便仅显示相关团队,而不显示所有可用团队。但是,我不想在 ComboBox 中显示 Team id
属性,我想显示 name
属性,因为它是在 teamsXml
中定义的>,例如,团队 A。当我从 id
获得团队 id
时,如何使用 DataTemplate
并以某种方式从 teamsXml
获取团队名称代码>productXml?我还希望 ComboBox 的值是 name
属性。
编辑:
我想知道这样的事情是否是朝着正确方向迈出的一步:
<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>
I have XML in the following format:
<Products>
<Product name="MyProduct1">
<Components>
<Component name="MyComponent1">
<Teams>
<Team id="1"/>
<Team id="4"/>
</Teams>
</Component>
</Components>
</Product>
</Products>
This is stored in an external XML file that is included via an XmlDataProvider
in my XAML:
<XmlDataProvider Source="Products.xml"
XPath="Products/Product"
x:Key="productsXml"/>
You'll see that the Team
nodes have only an id
attribute; this links them to other XML that is embedded directly in my XAML:
<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>
I have the following ComboBox in my XAML:
<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" />
This ComboBox shows a list of Teams associated with the currently selected Component. I need to keep DataContext
and ItemsSource
the same here so that only the related Teams are shown, and not all available Teams. However, I don't want to show the Team id
attribute in the ComboBox, I want to show the name
attribute as it is defined in teamsXml
, e.g., Team A. How can I use a DataTemplate
and somehow get the Team name from teamsXml
when I have the Team id
from productsXml
? I also want the value of the ComboBox to be the name
attribute.
Edit:
I'm wondering if something like this is a step in the right direction:
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
再说一次,这个家伙文章帮助了我。我将我的 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# 类:XmlConverter
和 XmlConverterParameter
。现在,我的 ComboBox 将团队 id
转换为 name
并显示 name
,因此我的 XML 相当干燥,因为团队名称仅在一个地方。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我将使用 Linq to xml 并填充 CollectionViewSource。然后绑定到它而不是 xmlDataProvider。
I'd use Linq to xml and fill a CollectionViewSource. Then bind to that rather than xmlDataProvider.