Привязать любой документ XML к WPF TreeView - PullRequest
7 голосов
/ 07 мая 2009

Я хотел бы привязать любой документ XML к WPF TreeView, используя TypeConverter.

Моим первоначальным решением было использование рекурсии, но когда документ большой, пользовательский интерфейс сильно связан.

Следующая ссылка говорит о TypeConverter, но для конкретной комбинации узел / элемент: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/edd843b7-b378-4c2d-926f-c053dbd7b340

Что если не известно, как выглядит XML-документ? Так как это только для целей отображения, на данный момент меня не волнует функциональность, я просто хочу связать XML с TreeView.

Ответы [ 3 ]

6 голосов
/ 28 апреля 2011

Работает для других типов узлов с несколькими простыми модификациями. Во-первых, для связывания XPath HierarchicalDataTemplate.ItemsSource необходимо изменить значение «child :: node () | attribute :: *», чтобы разрешить любой дочерний узел и любой атрибут. Затем добавьте DataTriggers для других типов NodeType. Пример ниже работал для меня. Обратите внимание, что я добавил значки для различных типов NodeType, вы можете удалить их:

        <HierarchicalDataTemplate x:Key="NodeTemplate">
        <StackPanel Orientation="Horizontal">
        <Image x:Name="icon" VerticalAlignment="Center" Margin="1,1,4,1"/>
        <TextBlock x:Name="name" Text="" />
        <TextBlock x:Name="inter" Text="" />
        <TextBlock x:Name="value" Text="" />
        </StackPanel>
        <HierarchicalDataTemplate.ItemsSource>
            <Binding XPath="child::node()|attribute::*" />
        </HierarchicalDataTemplate.ItemsSource>
        <HierarchicalDataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
                <Setter TargetName="icon" Property="Source" Value="icons/element.png"></Setter>
                <Setter TargetName="name" Property="Text" Value="{Binding Path=Name}"></Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="Text">
                <Setter TargetName="icon" Property="Source" Value="icons/text.png"></Setter>
                <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="Attribute">
                <Setter TargetName="icon" Property="Source" Value="icons/attribute.png"></Setter>
                <Setter TargetName="name" Property="Text" Value="{Binding Path=Name}"></Setter>
                <Setter TargetName="inter" Property="Text" Value=": "></Setter>
                <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="CDATA">
                <Setter TargetName="icon" Property="Source" Value="icons/cdata.png"></Setter>
                <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="Comment">
                <Setter TargetName="icon" Property="Source" Value="icons/comment.png"></Setter>
                <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="ProcessingInstruction">
                <Setter TargetName="icon" Property="Source" Value="icons/pi.png"></Setter>
                <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
            </DataTrigger>
        </HierarchicalDataTemplate.Triggers>
    </HierarchicalDataTemplate>
3 голосов
/ 03 июня 2009

Итак, я задал вопрос о том, как связать любой XML-документ, независимо от схемы, в виде дерева следующим образом: 1. Привязать XML-документ к WPF TreeView через провайдера XML и HierarchicalDataTemplate. 2. Отобразите все узлы XML-документа, включая те, которые имеют дочерние узлы, в следующем формате:

> Узел1

Node1 Содержание

    >ChildNode1

       ChildNode1 Contents

            >ChildNode1'sChildNode

              ChildNode1'sChildNode Contents

> Node2

  Node2 Contents

Проблема заключалась в том, что мой TreeView связывал каждое свойство имени XmlNode с TreeItem. В случае текстового XmlNode он связывал бы #text с TreeItem, что было не тем, что я хотел.

Итак, через сообщение на форуме MSDN я получил ответ: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/cbdb2420-1403-436f-aa7f-b1e3b1acb398/

Таким образом, хитрость заключалась в том, чтобы использовать триггеры для установки значения в зависимости от типа обнаруженного узла.

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

Вот XAML:

<Window x:Class="WpfApplication1.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1" Height="250" Width="450">

<Window.Resources>
    <HierarchicalDataTemplate x:Key="NodeTemplate">
        <TextBlock x:Name="text" Text="?" />
        <HierarchicalDataTemplate.ItemsSource>
            <Binding XPath="child::node()" />
        </HierarchicalDataTemplate.ItemsSource>
        <HierarchicalDataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="Text">
                <Setter TargetName="text" Property="Text" Value="{Binding Path=Value}"></Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
                <Setter TargetName="text" Property="Text" Value="{Binding Path=Name}"></Setter>
            </DataTrigger>
        </HierarchicalDataTemplate.Triggers>            
    </HierarchicalDataTemplate>
    <XmlDataProvider x:Key="xmlDataProvider"></XmlDataProvider>
</Window.Resources>

<Grid >
    <TreeView Name="treeView1"
              Background="AliceBlue"
              ItemsSource="{Binding Source={StaticResource xmlDataProvider}, XPath=*}"
              ItemTemplate= "{StaticResource NodeTemplate}"/>
</Grid>

public Window1()
{
InitializeComponent();
XmlDataProvider dataProvider = this.FindResource("xmlDataProvider") as XmlDataProvider;
        XmlDocument doc = new XmlDocument();
            // Testdocument        doc.LoadXml(
            @"<root>
                <child1>text1<child11>text11</child11>
                </child1>
                <child2>text2<child21>text21</child21>
                    <child22>text22</child22>
                </child2>
              </root>");
        dataProvider.Document = doc;
    }
1 голос
/ 23 ноября 2011

Посмотрите на мой ответ в следующей ветке - Привязка XML-данных к WPF TreeView Control Я считаю, что это именно то, что вы ищете. Ссылка в теме указывает на сообщение, которое дает пошаговый пример с возможностью загрузки исходного кода. Пример написан таким образом, чтобы связать любой XML-документ с представлением дерева WPF

...