Как привязать Xml-атрибут к узлам Treeview при привязке данных XDocument к WPF Treeview

StackOverflow https://stackoverflow.com/questions/238196

Вопрос

У меня есть XML, который должен быть привязан к базе данных Просмотр дерева WPF.Здесь XML может иметь разную структуру.TreeView должен быть достаточно общим для привязки к данным, чтобы загружать любую перестановку иерархии.Однако an Атрибут XAttribute ( XAttribute ) на узлах (называемых Название) должен быть привязан к базе данных treeviewitem's текст заголовка и не имя узла.

XML, который должен быть привязан:

<Wizard>
  <Section Title="Home">
    <Loop Title="Income Loop">
      <Page Title="Employer Income"/>
      <Page Title="Parttime Job Income"/>
      <Page Title="Self employment Income"/>
    </Loop>
  </Section>
  <Section Title="Deductions">
    <Loop Title="Deductions Loop">
      <Page Title="Travel spending"/>
      <Page Title="Charity spending"/>
      <Page Title="Dependents"/>
    </Loop>
  </Section>
</Wizard>

XAML:

<Window x:Class="Wpf.DataBinding.TreeViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Wpf.DataBinding"
    Title="TreeViewer" Height="300" Width="300">
    <Window.Resources>
        <HierarchicalDataTemplate ItemsSource="{Binding Path=Elements}" x:Key="TVTemplate">
            <TreeViewItem Header="{Binding Path=Name}"/>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <StackPanel>
        <TreeView x:Name="_treeView" Style="{StaticResource TVallExpanded}"
                ItemsSource="{Binding Path=Root.Elements}"
                ItemTemplate="{StaticResource TVTemplate}" />
    </StackPanel>
</Window>

codebehind XAML, который загружает XML в XDocument и привязывает его к TreeView

public partial class TreeViewer : Window
{
    public TreeViewer()
    {
        InitializeComponent();
        XDocument doc = XDocument.Parse(File.ReadAllText(@"C:\MyWizard.xml"));
        _treeView.DataContext = doc;
    }
}

Итак, в разметке XAML мы привязываем Name к заголовку TreeViewItem .

<TreeViewItem Header="{Binding Path=Name}"/>

Тем не менее, я хочу привязать его к Название атрибут раздела, Цикла и Страницы в приведенном выше XML.Я читал, что невозможно использовать XPath при привязке XDocument .Но должен быть способ связать Название атрибут к тексту заголовка TreeViewItem.Я пробовал использовать @Title, .[@Title] и т.д.Но, похоже, ничего из этого не сработало.

Это тема на форумах MSDN ведет аналогичную дискуссию.

Любые указания были бы очень полезны.

Это было полезно?

Решение

Ура !!!Я выяснил, как привязать XAttribute.Это не интуитивно понятно, и это нелегко вообразить.Но вот как это можно сделать.

<TreeViewItem Header="{Binding Path=Attribute[Title].Value}"/>

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

Подробнее по этой ссылке MSDN

Другие советы

Я думаю, все, что вам нужно сделать, это создать Иерархическая табличка данных для каждого типа узла в вашем XML-файле загрузите ваш xml-файл в XmlDataProvider - поставщик XML - данных, а затем свяжите это к просмотру дерева.Телевизор работает с XDP для привязки данных, и где-то по ходу дела они выясняют, какие HDT вы определили, и сопоставляют их тип данных с именами узлов в вашем XML.Возможно, у вас возникли некоторые проблемы с изменением ваших XPaths в зависимости от различных типов данных, но сохранение их гибкости - это другой вопрос.

Например, у меня есть небольшое тестовое приложение для регулярных выражений.Он включает в себя справочную систему, которая по сути представляет собой все различные части регулярных выражений, перечисленные в дереве:Категории и детали с описаниями, всплывающими подсказками и прочим.Данные о деталях хранятся в виде источника xml-данных.Поскольку он статичен, я просто создал статический ресурс с ресурсами приложения:

<XmlDataProvider
    x:Key="rxPartData"
    XPath="RegexParts">
    <x:XData>
        <RegexParts
            xmlns="">
            <Category
                Name="Character class"
                ToolTip="Sets of characters used in matching">
                <RegexPart
                    Regex="[%]"
                    Hint="Positive character group"
                    ToolTip="Matches any character in the specified group (replace % with one or more characters)" />
                <!-- yadda -->
            </Category>
        </RegexParts>
    </x:XData>
</XmlDataProvider>

Затем я создал Иерархические таблички с данными для каждого типа узла в данных (опять же, все это находится в ресурсах приложения):

<!-- Category data template -->
<HierarchicalDataTemplate
    DataType="Category"
    ItemsSource="{Binding XPath=*}">
    <TextBlock
        Focusable="False"
        Text="{Binding XPath=@Name}"
        ToolTip="{StaticResource CategoryTooltip}"
        ToolTipService.InitialShowDelay="0"
        ToolTipService.ShowDuration="{x:Static sys:Int32.MaxValue}"
        ToolTipService.HasDropShadow="True" />
</HierarchicalDataTemplate>
<!-- RegexPart data template -->
<HierarchicalDataTemplate
    DataType="RegexPart"
    ItemsSource="{Binding XPath=*}">
    <WrapPanel
        Focusable="False"
        ToolTip="{StaticResource RegexPartTooltip}"
        ToolTipService.InitialShowDelay="0"
        ToolTipService.ShowDuration="{x:Static sys:Int32.MaxValue}"
        ToolTipService.HasDropShadow="True">
        <TextBlock
            Text="{Binding XPath=@Regex}" />
        <TextBlock
            Text=" - " />
        <TextBlock
            Text="{Binding XPath=@Hint}" />
    </WrapPanel>
</HierarchicalDataTemplate>

Наконец, я просто привязал дерево к XmlDataProvider:

<TreeView
  Name="_regexParts"
  DockPanel.Dock="Top"
  SelectedItemChanged="RegexParts_SelectedItemChanged"
  ItemsSource="{Binding Source={StaticResource rxPartData}, XPath=/RegexParts/Category}"
  ToolTip="Click the + to expand a category; click a part to insert it">
</TreeView>

И это все, что вам нужно сделать.Древовидный вид и XmlDataProvider - поставщик XML - данных позаботится о поиске и использовании правильного HDT-х для правильных узлов в данных.Самая сложная часть всего этого - определить ваши xpaths для привязки.Это может стать немного сложнее, поскольку, если ваши пути неверны, вы в конечном итоге ничего не получите в дереве и не будет никаких ошибок (есть способы увеличить количество отчетов об ошибках при привязке данных в WPF, но это другой вопрос).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top