【问题标题】:XML Data Binding with NamespacesXML 数据绑定与命名空间
【发布时间】:2008-10-10 04:15:50
【问题描述】:

我想使用 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),列表框仍能正确显示名称,但单击这些名称不再更新名称和性别字段!我的怀疑是 xml 命名空间以某种方式对 groupbox 的 DataContext 做出了不利的反应,但我不确定为什么或如何。有谁知道如何在这种情况下使用 XML 命名空间?

【问题讨论】:

    标签: c# wpf xml data-binding namespaces


    【解决方案1】:

    我还在 MSDN WPF 表单上asked this question。 Marco Zhou 用这个回答了我,这最终是我想要的答案。我在这里复制了它,以供任何寻求相同答案的人使用:

    这行得通:

        <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.XmlNamespaceManager 附加 TextBlock 的属性。

    ListBox 是绑定到数据的数据 具有 xml 命名空间的提供程序 映射信息,但绑定 TextBlock 上没有这个 信息,这就是它失败的原因。

    其实在做master detail的时候 数据绑定,更适合 执行以下操作:

        <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>
    

    希望这能让事情变得更清楚 位。

    【讨论】:

      【解决方案2】:

      您可以像这样在 XPath 查询中使用本地名称:

       <TextBox Name="nameText">
          <TextBox.Text>
             <Binding XPath="*[local-name()='Name']" />
          </TextBox.Text>
       </TextBox>
      

      【讨论】:

      • 好的,这行得通,但我想在给出“已回答”标记之前了解更多原因。我对数据绑定很陌生,所以我不熟悉一些更高级的 synatx。 local-name() 到底在做什么?
      • local-name() 是一个 XPath 函数,它允许您仅使用其本地名称而不是全名(命名空间 + 本地名称)来选择 xml 元素
      • 啊,谢谢!现在这是有道理的。这是一个可行的解决方案,但我仍然很想知道为什么我失去了在这个级别使用命名空间进行查询的能力。不过,感谢您的帮助!
      • 我很抱歉,但是虽然您的回答很有帮助,但我还是以另一种形式向我提供了更全面的回答。我在这里复制了它,为了社区参考,我将它标记为已接受的答案。不过,感谢您的帮助,如果我可以将您的答案排名更高,我会的!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-07
      • 1970-01-01
      相关资源
      最近更新 更多