powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
25 сообщений из 168, страница 1 из 7
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36630607
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разбираюсь, как с помощью привязки к содержимому xml-файла, используя LINQ to XML, отобразить иерархию в элементе TreeView.
В качестве примера написал такой xml-файл исходных данных, которые следует отобразить в TreeView:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<?xml version="1.0" encoding="utf-8" ?>
<MyXmlDocument>
  <Category CategoryName="Компьютерная литература" Description ="Различная литература по компьютерной тематике" ToolTipText="Мой раздел">
    <Category CategoryName="Windows-приложения" Description ="Данная ОС наиболее популярна" ToolTipText="Моя ось">
      <Category CategoryName="MS Office 2007" Description ="Офисный пакет программ" ToolTipText="Мой офис"/>
      <Category CategoryName="Продукция компании Autodesk" Description ="Различные САПР" ToolTipText="Мой выбор">
        <Category CategoryName="AutoCAD" Description ="Самый распространённый САПР" ToolTipText="Мой САПР">
          <Book BookName ="AutoCAD 2010. Полещук Н.Н." Description ="Моя книжка по данному САПР" ToolTipText="Справочник"/>
          <Book BookName ="AutoCAD 2007, библия пользователя. (автора не помню)" Description ="Ещё одна моя книжка по данному САПР" ToolTipText="Справочник"/>
        </Category>
        <Category CategoryName="Revit" Description ="новое поколение САПР (BIM)" ToolTipText="Пока ещё не мой САПР"/>        
      </Category>
    </Category>
    <Category CategoryName="Linux-приложения" Description ="Свободно распространяемая ОС" ToolTipText="Интересно, но не сильно распространено"/>
  </Category>
  <Category CategoryName="Классика" Description ="Классическая литература" ToolTipText="Полезно для общего развития">
    <Category CategoryName="Поэзия" Description ="Стихи отечественных авторов" ToolTipText="Для души"/>
    <Category CategoryName="Повести и рассказы" Description ="Повести и рассказы отечественных авторов" ToolTipText="Это тоже для души"/>
  </Category>  
</MyXmlDocument>
Написал конвертер значений:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    //Конвертер для класса XElement. Задача этого конвертера - извлечение вложенных элементов типа XElement, инкапсулирующих
    //в себе разделы Category.
    public sealed class XmlConverter :IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is XElement)
            {
                XElement x = (XElement)value;
                return x.Elements("Category");
            }
            else
            {
                return null;
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
После этого создал файл ресурса, в котором определил нужный мне шаблон:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:linq2Xml="clr-namespace:System.Xml.Linq;assembly=System.Xml.Linq"                                      
                    xmlns:local="clr-namespace:WpfGuiProject">
    <!--Шаблон иерархического отображения данных В СЛУЧАЕ ПОДКЛЮЧЕНИЯ К XML-ФАЙЛУ -->
    <HierarchicalDataTemplate DataType="{x:Type linq2Xml:XElement}">
        <!--Указываю источник данных, на основании которого должно формироваться дерево разделов-->
        <HierarchicalDataTemplate.ItemsSource>
            <Binding Path=".">
                <!--Указываю конвертер, который позволяет получить список дочерних элементов типа Category, по отношению к данному-->
                <Binding.Converter>
                    <local:XmlConverter/>
                </Binding.Converter>
            </Binding>
        </HierarchicalDataTemplate.ItemsSource>
        <!--Формирую визуальное представление элемента, отображаемого в дереве разделов-->
        <TextBlock Text="{Binding Path=Attribute[CategoryName].Value}">
                <TextBlock.ToolTip>
                    <Binding Path="Attribute[ToolTipText].Value"/>
                </TextBlock.ToolTip>
        </TextBlock>
    </HierarchicalDataTemplate>
</ResourceDictionary>
После этого, в конструкторе окна размещаю такой код:
Код: plaintext
1.
2.
xml = XElement.Load(@"..\..\XMLFile1.xml");
treeStructure.ItemsSource = xml.Elements("Category");//treeStructure - элемент TreeView
Однако я не получаю разворачивающейся древовидной структуры, состоящей из имён элементов и всплывающих "ТуллТипов", как прописывал это в xaml-разметке шаблона. Результат выглядит так:



Искал в интернете примеры по иерархическому отображению структуры, считанное с использованием linq to xml и реализованное в виде привязки - мало что нашел. На основании того что нашёл и написал выше обозначенный код.

Что я сделал не верно?
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36630907
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Консольное приложение (код ниже) делает по своей сути то же самое, что и код топика, и всё отображает верно:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        //Шаг смещения дочерних элементов в древовидном отображении
        static string tab = new string(' ', 2);

        //точка входа
        static void Main(string[] args)
        {
            XElement xml = XElement.Load("XMLFile1.xml");
            NewMethod(xml, string.Empty);
            Console.Read();
        }

        //рекурсивный метод построения структуры каталогов (отображает их имена)
        private static void NewMethod(XElement xml, string tab1)
        {
            foreach (XElement item in xml.Elements("Category"))
            {
                Console.WriteLine("{0}{1}", tab1, item.Attribute("CategoryName").Value);//В оригинале аналогичным образом указано, значение какого атрибута следует отображать
                NewMethod(item, tab1 + tab);
            }
        }
    }
}
результат такой:

...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36630936
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если закомментировать часть шаблона, как показано ниже:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
    <!--Шаблон иерархического отображения данных В СЛУЧАЕ ПОДКЛЮЧЕНИЯ К XML-ФАЙЛУ -->
    <HierarchicalDataTemplate DataType="{x:Type linq2Xml:XElement}">
        <!--Указываю источник данных, на основании которого должно формироваться дерево разделов-->
        <HierarchicalDataTemplate.ItemsSource>
            <Binding Path=".">
                <!--Указываю конвертер, который позволяет получить список дочерних элементов типа Category, по отношению к данному-->
                <!--<Binding.Converter>
                    <local:XmlConverter/>
                </Binding.Converter>-->
            </Binding>
        </HierarchicalDataTemplate.ItemsSource>
        <!--Формирую визуальное представление элемента, отображаемого в дереве разделов-->
        <!--<TextBlock Text="{Binding Path=Attribute[CategoryName].Value}">
                <TextBlock.ToolTip>
                    <Binding Path="Attribute[ToolTipText].Value"/>
                </TextBlock.ToolTip>
        </TextBlock>-->
    </HierarchicalDataTemplate>
то результат будет тот же самый, что был показан мною на скрине выше. Отсюда вывод - созданный мною для xml-данных шаблон не работает. Хотелось бы понять почему.
____________________________________
п.с. тихо сам с собою, я веду беседу...
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631596
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если в отладчике посмотреть, в конвертере вот это условие
...
if (value is XElement)
...
проходит (true)?
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631633
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 МСУ
Обещанная ссылка на упрощённый вариант исходников (выбросил всё, что связано с БД).
LRЕсли в отладчике посмотреть, в конвертере вот это условие
...
if (value is XElement)
...
проходит (true)?
как я уже писал выше - мой шаблон попросту не работает, и в процессе работы код просто не доходит до этой точки.
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631665
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей, Вы заготовили тестовый проект, как я просил?
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631696
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУАндрей, Вы заготовили тестовый проект, как я просил?
Ну да. В последнем линке - это вообще "лайт" версия, в которой оставлено только всё то, что относится непосредственно к озвученной проблеме. Весь код, относящийся к базе данных выброшен.
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631706
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum
Сорри, я просто увидел в архиве Linq2Sql проект, какой-то ConsoleApplication1 проект и подумал, что Вы нихрена не сделали. Теперь вижу, вы просто их исключили из солюшена ;)
Такой вопрос навскидку: а Вам обязателен ResourceDictionary, напрямую в MainWindow.xaml не хотите HierarchicalDataTemplate закурить?
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631725
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, у Вас в справочнике прописан ожидаемый тип шаблона: DataType="{x:Type linq2Xml:XElement}"
Следовательно, о каком вообще xml речь? Типизируйте айтемы коллекции к данному типу и подгружайте в дерево.
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631738
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositumкак я уже писал выше - мой шаблон попросту не работает, и в процессе работы код просто не доходит до этой точки.
если в TreeView указать этот шаблон (ItemTemplate="{StaticResource myHierarchicalTemplate}"), то все будет работать...
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631743
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУCompositum
Сорри, я просто увидел в архиве Linq2Sql проект, какой-то ConsoleApplication1 проект и подумал, что Вы нихрена не сделали. Теперь вижу, вы просто их исключили из солюшена ;)
Такой вопрос навскидку: а Вам обязателен ResourceDictionary, напрямую в MainWindow.xaml не хотите HierarchicalDataTemplate закурить?
Это сути проблемы не изменит. Я предпочитаю выносить ресурсы за рамки xaml-разметки элемента, т.к. таким ресурсом (в случае необходимости) можно будет воспользоваться не только в MainWindow.xaml
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631745
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати, Dictionary1.xaml в примере не подгружается, шаблон не имеет ключа, я задал ему x:Key="myHierarchicalTemplate" и перенес в Application.Resources - все заработало
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631758
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
<TreeView Name="treeStructure" Margin="2" Grid.Row="1"
             ItemsSource="{Binding Path=Root.Elements}"              
             ItemTemplate="{StaticResource template}"
/>

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:linq2Xml="clr-namespace:System.Xml.Linq;assembly=System.Xml.Linq"                                        
                    xmlns:local="clr-namespace:WpfGuiProject">

    <!--Шаблон иерархического отображения данных В СЛУЧАЕ ПОДКЛЮЧЕНИЯ К XML-ФАЙЛУ -->
    <HierarchicalDataTemplate x:Key="template">
        <!--Указываю источник данных, на основании которого должно формироваться дерево разделов-->
        <HierarchicalDataTemplate.ItemsSource>
            <Binding Path="Elements">
                <!--Указываю конвертер, который позволяет получить список дочерних элементов типа Category, по отношению к данному-->
                <Binding.Converter>
                    <local:XmlConverter/>
                </Binding.Converter>
            </Binding>
        </HierarchicalDataTemplate.ItemsSource>
        <!--Формирую визуальное представление элемента, отображаемого в дереве разделов-->
        <TextBlock Text="{Binding Path=Attribute[CategoryName].Value}">
                <TextBlock.ToolTip>
                    <Binding Path="Attribute[ToolTipText].Value"/>
                </TextBlock.ToolTip>
        </TextBlock>
    </HierarchicalDataTemplate>
</ResourceDictionary>
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631760
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
+1 к x:Key, у меня тоже с ним работает. И его нужно привязать к ItemTemplate.
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631768
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRкстати, Dictionary1.xaml в примере не подгружается, шаблон не имеет ключа, я задал ему x:Key="myHierarchicalTemplate" и перенес в Application.Resources - все заработало
у меня всё подгружается. В Application.Resources ресурсы не переношу принципиально - если это окно использовать в плагинах (например в AutoCAD), то в том случае, когда окошко будет хранить ресурсы в Application.Resources - не получится создать экземпляр этого окна. т.к. там приходится создавать окно так:
Код: plaintext
MyWin win = new MyWin(); 
А ежели в XAML-разметке MyWin будет ссылка на ресурс, хранящийся в Application.Resources, то таким образом не удастся создать экземпляр класса MyWin, т.к. это означает, что сначала нужно создать экземпляр приложения и затем, при создании экземпляра MyWin, как-то указать ему, в экземпляре какого класса (производного от Application) искать ресурсы. Это как-то геморно.
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631779
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Относительно ключа - тогда уж лучше прописывать как-то так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:linq2Xml="clr-namespace:System.Xml.Linq;assembly=System.Xml.Linq"                                        
                    xmlns:local="clr-namespace:WpfGuiProject">

    <!--Шаблон иерархического отображения данных В СЛУЧАЕ ПОДКЛЮЧЕНИЯ К XML-ФАЙЛУ -->
    <HierarchicalDataTemplate x:Key="{x:Type linq2Xml:XElement}" DataType="{x:Type linq2Xml:XElement}">
        <!--Указываю источник данных, на основании которого должно формироваться дерево разделов-->
        <HierarchicalDataTemplate.ItemsSource>
            <Binding Path=".">
                <!--Указываю конвертер, который позволяет получить список дочерних элементов типа Category, по отношению к данному-->
                <Binding.Converter>
                    <local:XmlConverter/>
                </Binding.Converter>
            </Binding>
        </HierarchicalDataTemplate.ItemsSource>
        <!--Формирую визуальное представление элемента, отображаемого в дереве разделов-->
        <TextBlock Text="{Binding Path=Attribute[CategoryName].Value}">
                <TextBlock.ToolTip>
                    <Binding Path="Attribute[ToolTipText].Value"/>
                </TextBlock.ToolTip>
        </TextBlock>
    </HierarchicalDataTemplate>
</ResourceDictionary>
теоретически, в этом случае, если мне не изменяет память, шаблон будет автоматически применяться ко всем встречающимся XElement
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631787
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
однако я по прежнему не получаю нужного результата
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631802
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositumоднако я по прежнему не получаю нужного результата
Я не понимаю смысла Вашего конвертера. Он как-бы должен отбирать элементы Category. Дык они и так биндятся:

Код: plaintext
treeStructure.ItemsSource = XElement.Load(@"..\..\XMLFile1.xml").Elements("Category");

Во-вторых, в метод XmlConverter.Convert приходит не XElement, а ReadOnlyObservableCollection.
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631905
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУ
Я не понимаю смысла Вашего конвертера. Он как-бы должен отбирать элементы Category. Дык они и так биндятся:
Код: plaintext
treeStructure.ItemsSource = XElement.Load(@"..\..\XMLFile1.xml").Elements("Category");
Это лишь первый уровень иерархии. Он должен отбирать дочерние элементы Category элемента Category.
[quot МСУ]в метод XmlConverter.Convert приходит не XElement, а ReadOnlyObservableCollection.
Если задать шаблону ключ:
Код: plaintext
1.
<HierarchicalDataTemplate x:Key="xxx" DataType="{x:Type linq2Xml:XElement}">
и затем привязать его в xaml-разметке элемента TreeView:
Код: plaintext
<TreeView Name="treeStructure" Margin="2" Grid.Row="1" ItemTemplate="{StaticResource ResourceKey=xxx}" />
то древовидная структура строится. Спасибо.
Я не понимаю такого момента - почему такая разметка:
Код: plaintext
<HierarchicalDataTemplate x:Key="{x:Type linq2Xml:XElement}" DataType="{x:Type linq2Xml:XElement}">
не даёт желанного результата. (((
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631931
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumЯ не понимаю такого момента - почему такая разметка:
Код: plaintext
<HierarchicalDataTemplate x:Key="{x:Type linq2Xml:XElement}" DataType="{x:Type linq2Xml:XElement}">
не даёт желанного результата. (((
Вы хоть сами поняли, что написали? :)
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631950
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУCompositumЯ не понимаю такого момента - почему такая разметка:
Код: plaintext
<HierarchicalDataTemplate x:Key="{x:Type linq2Xml:XElement}" DataType="{x:Type linq2Xml:XElement}">
не даёт желанного результата. (((
Вы хоть сами поняли, что написали? :)
Конечно Даниил. А Вы разве не в курсе, что назначение ключу подобного имени приводит к тому, что данный шаблон будет автоматом цепляться всеми элементами данного типа (т.е. им не нужно указывать шаблон)?
я это у Криса Андерсона срисовал давно )
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36631971
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
он пишет на эту тему на стр. 374.
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36632008
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositumя это у Криса Андерсона срисовал давно )
Хм, а, разве, не к Style только можно применять такую фичу? Честно говоря, не знал. Спасибо! :)
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36632025
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУCompositumя это у Криса Андерсона срисовал давно )
Хм, а, разве, не к Style только можно применять такую фичу? Честно говоря, не знал. Спасибо! :)
блиииииин... точно... это только к стилям. извиняюсь тогда всё встаёт на свои места. это меня перемкнуло, что можно и к шаблонам (((
...
Рейтинг: 0 / 0
Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
    #36632040
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
25 сообщений из 168, страница 1 из 7
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Иерархическое отображение данных xml-файла в элементе TreeView с помощью привязки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]