Элементы управления связыванием XmlDataProvider с дочерними элементами

В следующем коде я не могу получить доступ к элементам параметров в файле XML. ListBox отображает все инструкции в файле XML. Предполагается, что ComboBox отображает все элементы Parameters, связанные с выбранной инструкцией в ListBox. Содержание ComboBox - вот где у меня проблема. Ничего не отображается с предоставленным кодом ниже.

<Window x:Class="LinqToXmlDataBinding.L2XDBForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF Data Binding using LINQ-to-XML" Height="750" Width="500" ResizeMode="CanResize">

<Window.Resources>
    <XmlDataProvider x:Key="XMLInstructionsMapping" Source="XMLMapping.xml"       XPath="InstructionsMapping/Instruction"/>

    <!-- Template for use in Books List listbox. -->
    <DataTemplate x:Key="InstructionTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Margin="3" Text="{Binding XPath=@Name}"/>
            <TextBlock Margin="3" Text="-"/>
            <TextBlock Margin="3" Text="ConvertedFrom: "/>
            <TextBlock Margin="3" Text="{Binding XPath=@ConvertedFrom}"/>
        </StackPanel>          
    </DataTemplate>
    <DataTemplate x:Key="ParamterTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Margin="3" Text="Name: "/>
            <TextBlock Margin="3" Text="{Binding XPath=@Name}"/>
            <TextBlock Margin="3" Text="-"/>
            <TextBlock Margin="3" Text="DataType: "/>
            <TextBlock Margin="3" Text="{Binding XPath=@DataType}"/>
            <TextBlock Margin="3" Text="-"/>
            <TextBlock Margin="3" Text="Direction: "/>
            <TextBlock Margin="3" Text="{Binding XPath=@Direction}"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

<!-- Main visual content container -->
<StackPanel Background="lightblue" DataContext="{Binding Source={StaticResource XMLInstructionsMapping}}">

    <!-- List box to display all instructions section -->
    <DockPanel Margin="5">
        <Label  Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" FontWeight="Bold">Instruction List
            <Label.LayoutTransform>
                <RotateTransform Angle="90"/>
            </Label.LayoutTransform>
        </Label>

        <ListBox x:Name="lbBooks" Height="200" Width="415" 
                 ItemsSource="{Binding Source={StaticResource XMLInstructionsMapping}}"
                 ItemTemplate ="{StaticResource InstructionTemplate}"                    
                 IsSynchronizedWithCurrentItem="True" SelectionMode="Single" Visibility="Visible">
        </ListBox>            
    </DockPanel>

    <Label  Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" FontWeight="Bold">Parameter List
    </Label>
    <!-- Combobox to display all selected instruction's parameters -->
    <ComboBox x:Name="lstParams" Margin="5" Height="30" Width="415"
                 ItemsSource="{Binding Source={StaticResource XMLInstructionsMapping}, XPath=InstructionsMapping/Instruction/Parameters/Parameter}"
                 ItemTemplate ="{StaticResource ParamterTemplate}"                    
                 IsSynchronizedWithCurrentItem="True" Visibility="Visible">
    </ComboBox>  
</StackPanel>

Вот файл XML, к которому я привязываюсь:

<?xml version="1.0" encoding="utf-8"?>
<InstructionsMapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Instruction Name="XIE" ConvertedFrom="XIC" >
    <Parameters>
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
    </Parameters>
  </Instruction>
  <Instruction Name="XIC" ConvertedFrom="XIC" >
    <Parameters>
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
      <Parameter Name="In1" Direction="Input" DataType="Bool" />
    </Parameters>
  </Instruction>
</InstructionsMapping>

Я пытаюсь заполнить ComboBox с параметрами выбранной инструкции в ListBox

Я использую XmlDataProvider связать с файлом XML. Я не могу понять выражение XPath (может быть, я что-то упускаю), которое мне нужно для отображения дочерних элементов инструкций.

Приветствуется любая помощь в выражении XPath, необходимом для этого.

1 ответ

Решение

Сначала удали XPath из ресурса XMLInstructionsMapping, Объявите это так:

<XmlDataProvider x:Key="XMLInstructionsMapping" Source="XMLMapping.xml"/>

Explanation - Позвольте XMLDataProvider загрузить полный файл XML вместо определенного узла в XML.


Во-вторых, установить XPath на ItemsSource of ListBox как это:

<ListBox x:Name="lbBooks" Height="200" Width="415" 
         ItemsSource="{Binding Source={StaticResource XMLInstructionsMapping},
                               XPath=InstructionsMapping/Instruction}" <-- HERE
         ItemTemplate ="{StaticResource InstructionTemplate}"                    
         IsSynchronizedWithCurrentItem="True" SelectionMode="Single" 
         Visibility="Visible">
</ListBox>

Explanation - Переместите XPath из ресурса сюда, чтобы получить конкретный узел.


В-третьих, обновить XPath в comboBox ItemsSource к этому:

<ComboBox x:Name="lstParams" Margin="5" Height="30" Width="415"
        ItemsSource="{Binding Source={StaticResource XMLInstructionsMapping}, 
                       XPath=InstructionsMapping/Parameters/Parameter}" <-- HERE
        ItemTemplate ="{StaticResource ParamterTemplate}"                    
        IsSynchronizedWithCurrentItem="True" Visibility="Visible">
</ComboBox>

Explanation - Установите правильный XPath, чтобы он указывал на узлы, которыми вы хотите заполнить comboBox.


ОБНОВИТЬ

Если вы хотите показать только элементы, соответствующие элементу, выбранному в listBox, вы можете выполнить привязку, используя ElementName с такими дочерними узлами, как это:

<ComboBox x:Name="lstParams" Margin="5" Height="30" Width="415"
        ItemsSource="{Binding Path=SelectedItem.ChildNodes[0].ChildNodes, 
                              ElementName=lbBooks}"
        ItemTemplate ="{StaticResource ParamterTemplate}"                    
        IsSynchronizedWithCurrentItem="True" Visibility="Visible">
</ComboBox>
Другие вопросы по тегам