Связывание данных XML с пространствами имен - PullRequest
3 голосов
/ 10 октября 2008

Я хочу использовать привязку данных к документу 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 негативно реагирует на DataContext группы, но я не уверен, почему и как. Кто-нибудь знает, как использовать пространства имен XML в этом контексте?

Ответы [ 2 ]

2 голосов
/ 16 октября 2008

Я также задал этот вопрос в формах 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>

Надеюсь, это немного прояснит ситуацию бит.

1 голос
/ 10 октября 2008

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

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