none
Создание Menu и связанного ListBox из XML (WPF) RRS feed

  • Общие обсуждения

  • Осваиваю WPF. И пытаюсь создать его средствами, без привлечения кода, меню из файла XML.

    Образец XML такой:

    <?xml version="1.0" encoding="utf-8" ?>
    <Menu DisplayMenuName="Главное меню">
      <MenuItem DisplayName="Пункт 1">
        <SubItem DisplaySubName="ПодПункт 1-1">
          <ListItem DisplayListName="Строка 1-1-1"/>
          <ListItem DisplayListName="Строка 1-1-2"/>
        </SubItem>
        <SubItem DisplaySubName="ПодПункт 1-2"/>
      </MenuItem>
      <MenuItem DisplayName="Пункт 2">
        <SubItem DisplaySubName="ПодПункт 2-1"/>
        <SubItem DisplaySubName="ПодПункт 2-2">
          <ListItem DisplayListName="Строка 2-2-1"/>
          <ListItem DisplayListName="Строка 2-2-2"/>
          <ListItem DisplayListName="Строка 2-2-3"/>
        </SubItem>
        <SubItem DisplaySubName="ПодПункт 2-3">
          <ListItem DisplayListName="Строка 2-3-1"/>
        </SubItem>
      </MenuItem>
      <MenuItem DisplayName="">
        <SubItem DisplaySubName="ПодПункт 3-1">
          <ListItem DisplayListName="Строка 3-1-1"/>
          <ListItem DisplayListName="Строка 3-1-2"/>
          <ListItem DisplayListName="Строка 3-1-3"/>
        </SubItem>
      </MenuItem>
      <MenuItem DisplayName="Пункт 4">
        <SubItem DisplaySubName="ПодПункт 4-1">
          <ListItem DisplayListName="Строка 4-1-1"/>
          <ListItem DisplayListName=""/>
          <ListItem DisplayListName="Строка 4-1-3"/>
        </SubItem>
        <SubItem DisplaySubName="ПодПункт 4-2"/>
        <SubItem DisplaySubName="">
          <ListItem DisplayListName="Строка 4-3-1"/>
        </SubItem>
        <SubItem DisplaySubName="ПодПункт 4-4">
          <ListItem DisplayListName="Строка 4-4-1"/>
          <ListItem DisplayListName="Строка 4-4-2"/>
        </SubItem>
      </MenuItem>
      <MenuItem>
        <SubItem DisplaySubName="ПодПункт 5-1">
          <ListItem DisplayListName="Строка 5-1-1"/>
          <ListItem DisplayListName="Строка 5-1-2"/>
          <ListItem DisplayListName="Строка 5-1-3"/>
        </SubItem>
        <SubItem DisplaySubName="ПодПункт 5-2">
          <ListItem DisplayListName="Строка 5-2-1"/>
          <ListItem DisplayListName="Строка 5-2-2"/>
        </SubItem>
      </MenuItem>
    </Menu>   

    То что сам смог написать

    <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>

            <StackPanel>
                <StackPanel.Resources>

                    <XmlDataProvider x:Key="xmldata" Source="MenuXML.xml" XPath="/Menu/MenuItem" />

                    <HierarchicalDataTemplate x:Key="NodeTemplate" 
                                              ItemsSource="{Binding XPath=SubItem[@DisplaySubName\!\=\'\']}">

                        <TextBlock x:Name="text"/>

                        <HierarchicalDataTemplate.Triggers>
                            <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
                                <Setter TargetName="text" Property="Text" Value="{Binding Path=Name}"></Setter>
                            </DataTrigger>

                            <DataTrigger Binding="{Binding Path=Name}" Value="MenuItem">
                                <Setter TargetName="text" Property="Text" Value="{Binding XPath=@DisplayName}"></Setter>
                            </DataTrigger>

                            <DataTrigger Binding="{Binding Path=Name}" Value="SubItem">
                                <Setter TargetName="text" Property="Text" Value="{Binding XPath=@DisplaySubName}"/>
                            </DataTrigger>

                            <DataTrigger Binding="{Binding Path=Name}" Value="ListItem">
                                <Setter TargetName="text" Property="Text" Value="{Binding XPath=@DisplayListName}"/>
                            </DataTrigger>
                        </HierarchicalDataTemplate.Triggers>
                    </HierarchicalDataTemplate>

                </StackPanel.Resources>
                <Menu
                    DataContext="{StaticResource xmldata}"
                    ItemsSource="{Binding XPath=[@DisplayName!\=\'\']}" 
                    ItemTemplate="{DynamicResource NodeTemplate}"
                    >
                </Menu>

            </StackPanel>
            <StackPanel Grid.Row="1">
                <ListBox x:Name="ListBox1"/>
                <TextBox x:Name="TextBox1" Height="23" TextWrapping="Wrap" Text="TextBox"/>

            </StackPanel>

        </Grid>

    Задачу хотел осуществить такую:

    1. Первый уровень меню формируется по XML-элементам MenuItem у которых есть атрибут DisplayName и он не пустой. В меню отображается значение атрибута DisplayName. (Здесь не смог создать фильтр для отсева пустых)

    2. Второй уровень меню формируется по дочерним элементам SubItem, так же у которых есть атрибут DisplaySubName и он не пустой. (Эта часть, вроде, работает)

    3. После выбора пункта меню второго уровня, его дочерние элементы связываются с ListBox. В котором отображаются элементы ListItem у  которых есть атрибут DisplayListName и он не пустой.(С этой часть, вообще, не понял - возможно это в WPF или нет. Наверное, надо обработчик Click писать на C# коде?)

    Как это можно сделать это на WPF с минимальным привлечением кода?

    16 августа 2018 г. 21:14