带有命名空间的XML数据绑定
本文关键字:XML 数据绑定 命名空间 | 更新日期: 2023-09-27 17:48:52
我想使用XML文档的数据绑定来填充一个显示人员列表详细信息的简单表单。我现在已经把一切都设置好了,并像现在这样工作:
<Window x:Class="DataBindingSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1">
<Window.Resources>
<XmlDataProvider x:Key="xmlProvider" XPath="People" Source="c:'someuri.xml"/>
</Window.Resources>
<Grid>
<ListBox Name="personList" ItemsSource="{Binding Source={StaticResource xmlProvider}, XPath=Person}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<GroupBox Header="GroupBox" Name="groupBox1" DataContext="{Binding ElementName=personList, Path=SelectedItem}">
<Grid>
<TextBox Name="nameText" Text="{Binding XPath=Name}"/>
<ComboBox Name="genderCombo" Text="{Binding XPath=Gender}">
<ComboBoxItem>Male</ComboBoxItem>
<ComboBoxItem>Female</ComboBoxItem>
</ComboBox>
</Grid>
</GroupBox>
</Grid>
</Window>
(为清晰起见,已删除所有位置/布局元素)
现在这很好用!如果我为它提供一些与所提供的路径匹配的XML,我会在列表框中获得一个名称列表,当单击时,该列表会在相应的字段中显示名称和性别。当我开始尝试在XML源中使用名称空间时,问题就出现了。XAML然后更改为如下所示:
<Window x:Class="DataBindingSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1">
<Window.Resources>
<XmlNamespaceMappingCollection x:Key="namespaceMappings">
<XmlNamespaceMapping Uri="http://www.mynamespace.com" Prefix="mns"/>
</XmlNamespaceMappingCollection>
<XmlDataProvider x:Key="xmlProvider" XmlNamespaceManager="{StaticResource namespaceMappings}" XPath="mns:People" Source="c:'someuriwithnamespaces.xml"/>
</Window.Resources>
<Grid>
<ListBox Name="personList" ItemsSource="{Binding Source={StaticResource xmlProvider}, XPath=mns:Person}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=mns:Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<GroupBox Header="GroupBox" Name="groupBox1" DataContext="{Binding ElementName=personList, Path=SelectedItem}">
<Grid>
<TextBox Name="nameText" Text="{Binding XPath=mns:Name}"/>
<ComboBox Name="genderCombo" Text="{Binding XPath=mns:Gender}">
<ComboBoxItem>Male</ComboBoxItem>
<ComboBoxItem>Female</ComboBoxItem>
</ComboBox>
</Grid>
</GroupBox>
</Grid>
</Window>
有了这段代码(当然还有适当的名称空间xml),Listbox仍然可以正确地显示名称,但单击这些名称不再更新Name和Gender字段!我怀疑xml名称空间在某种程度上对groupbox的DataContext产生了不利的反应,但我不确定原因或方式。有人知道如何在这种情况下使用XML名称空间吗?
我还在MSDN WPF表单上问了这个问题。周回答了我这个问题,这也是我一直在寻求的答案。我在这里复制了它,以方便任何寻求相同答案的人:
这项工作:
<XmlDataProvider x:Key="dataProvider" XmlNamespaceManager="{StaticResource namespaceMappings}" XPath="p:players/p:player"> <x:XData> <p:players xmlns:p="http://www.footballism.com/2005/SoccerPlayers"> <p:player> <p:fullName>Sebastian Batistuta</p:fullName> <p:age>26</p:age> </p:player> <p:player> <p:fullName>Andriey Shevchenko</p:fullName> <p:age>30</p:age> </p:player> <p:player> <p:fullName>Paviel Nedved</p:fullName> <p:age>21</p:age> </p:player> <p:player> <p:fullName>David Beckham</p:fullName> <p:age>19</p:age> </p:player> </p:players> </x:XData> </XmlDataProvider> </Page.Resources> <StackPanel> <TextBlock Text="{Binding XPath=p:fullName}" FontWeight="Bold" Binding.XmlNamespaceManager="{StaticResource namespaceMappings}" DataContext="{Binding ElementName=listBox, Path=SelectedItem}"/> <ListBox ItemsSource="{Binding Source={StaticResource dataProvider}}" x:Name="listBox" DisplayMemberPath="p:fullName"> </ListBox> </StackPanel> </Page>
我想看了代码之后,你应该能够理解为什么它在指定已附加Binding.XmlNamespaceManagerTextBlock的属性。
ListBox是绑定到数据的数据具有xml命名空间的提供程序映射信息,但绑定上没有这个信息,这就是它失败的原因。
实际上,在做细节大师时数据绑定,更适合做如下操作:
<XmlDataProvider x:Key="dataProvider" XmlNamespaceManager="{StaticResource namespaceMappings}" XPath="p:players/p:player"> <x:XData> <p:players xmlns:p="http://www.footballism.com/2005/SoccerPlayers"> <p:player> <p:fullName>Sebastian Batistuta</p:fullName> <p:age>26</p:age> </p:player> <p:player> <p:fullName>Andriey Shevchenko</p:fullName> <p:age>30</p:age> </p:player> <p:player> <p:fullName>Paviel Nedved</p:fullName> <p:age>21</p:age> </p:player> <p:player> <p:fullName>David Beckham</p:fullName> <p:age>19</p:age> </p:player> </p:players> </x:XData> </XmlDataProvider> </Page.Resources> <StackPanel DataContext="{Binding Source={StaticResource dataProvider}}"> <TextBlock Text="{Binding XPath=p:fullName}" FontWeight="Bold"/> <ListBox ItemsSource="{Binding}" x:Name="listBox" DisplayMemberPath="p:fullName" IsSynchronizedWithCurrentItem="True"> </ListBox> </StackPanel> </Page>
希望这能让事情稍微好转一点
您可以在XPath查询中使用本地名称,如下所示:
<TextBox Name="nameText">
<TextBox.Text>
<Binding XPath="*[local-name()='Name']" />
</TextBox.Text>
</TextBox>