2008-10-10 2 views
3

Я хочу использовать привязку данных к XML-документу, чтобы заполнить простую форму, содержащую сведения о списке людей. У меня есть все это настроить и работать, как это прямо сейчас:Связывание данных 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 отрицательно реагирует на DataContext groupbox, но я не уверен, почему и как. Кто-нибудь знает, как использовать пространства имен XML в этом контексте?

ответ

1

Вы можете использовать локальные имена в своих запросах XPath, как это:

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

Хорошо, это работает, но я хотел бы узнать немного больше о том, почему, прежде чем дать «ответную» печать. Я новичок в привязке данных, поэтому я не знаком с некоторыми более продвинутыми синтаксисами. Что такое local-name() здесь? – Toji 2008-10-10 15:18:54

2

asked this question Я также на формах 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.XmlNamespaceManager прилагается для TextBlock.

ListBox это данные связаны с данными поставщика, который имеет XML пространство имен информацию отображения, но связывание на TextBlock не имеет этой информации, поэтому она выходит из строя.

На самом деле, при выполнении мастера-детали связывания данных, это более уместно сделать что-то вроде следующий:

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

Надеется, что это очищает вещи немного немного.