Comment lier un attribut XML aux nœuds de Treeview, tout en liant des données XDocument à WPF Treeview

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

Question

J'ai un fichier XML qui doit être lié à une arborescence WPF . Ici, le XML peut avoir une structure différente. Le TreeView doit être suffisamment générique lié aux données pour charger toute permutation de hiérarchie. Toutefois, un XAttribute sur les nœuds (appelé Titre ) doit être lié au texte d'en-tête de TreeViewItem et pas au nom de noeud . .

XML à lier:

<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>

Le code ci-dessous de XAML qui charge XML dans XDocument et le lie à TreeView

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

Ainsi, dans le balisage XAML, nous lions Name à l'en-tête de TreeViewItem.

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

Toutefois, je souhaite le lier à l'attribut Titre de Section, Loop and Page dans le XML ci-dessus. J'ai lu qu'il n'était pas possible d'utiliser XPath en liant XDocument. Cependant, il doit exister un moyen de lier l'attribut Titre au texte d'en-tête de TreeViewItem. J'ai essayé d'utiliser @Title,. [@ Title] etc. Mais aucun ne semblait fonctionner.

Cette fil de discussion sur Les forums MSDN ont une discussion similaire.

Tous les indicateurs seraient grandement utiles.

Était-ce utile?

La solution

Hourra !!! J'ai compris comment lier XAttribute. Ce n'est pas intuitif et ce n'est pas facilement imaginable. Mais voici comment cela peut être fait.

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

Il est difficile d’imaginer que Title puisse être utilisé directement entre accolades.

Plus @ ce lien MSDN

Autres conseils

Je pense que tout ce que vous avez à faire est de créer un HierarchicalDataTemplate pour chaque type de noeud dans votre code XML, chargez-le dans un XmlDataProvider , puis liez cela à TreeView. Le téléviseur fonctionne avec le protocole XDP pour lier les données. Quelque part dans la même ligne, ils déterminent les HDT que vous avez définis et font correspondre leur type de données aux noms des noeuds de votre code XML. Vous avez peut-être des problèmes à modifier vos XPATH avec les différents types de données, mais garder ces données flexibles est une autre question.

Par exemple, j'ai une petite application de test regex. Il comprend un système d’aide qui regroupe essentiellement les différentes parties d’une expression rationnelle répertoriées dans une arborescence: Catégories et parties avec descriptions, info-bulles et autres éléments. Les données sur les pièces sont stockées sous forme de source de données XML. Depuis sa statique, je viens de créer une ressource statique avec les ressources de l'application:

<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>

Ensuite, j'ai créé HierarchicalDataTemplates pour chaque type de nœud dans les données (là encore, tout cela est dans les ressources de l'application):

<!-- 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>

Enfin, je viens de lier l’arborescence à 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>

Et c'est tout ce que vous avez à faire. TreeView et le XmlDataProvider se chargeront de trouver et d'utiliser le fichier correct HDT pour les nœuds appropriés dans les données. La partie la plus difficile de tout cela consiste à déterminer votre xpath pour la liaison. Cela peut devenir un peu délicat, car si vos chemins sont incorrects, vous n'obtiendrez rien dans l'arborescence et il n'y aura aucune erreur (il existe des moyens d'augmenter le rapport d'erreur dans la liaison de données dans WPF, mais c'est une autre question) .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top