Cómo enlazar el atributo XML a los nodos de la vista de árbol, mientras se vincula el archivo XDocument a la vista de árbol de WPF

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

Pregunta

Tengo un XML que debe estar vinculado a un WPF TreeView . Aquí el XML puede tener una estructura diferente. El TreeView debe ser lo suficientemente genérico para cargar cualquier permutación de jerarquía. Sin embargo, un XAttribute en los nodos (llamado Título ) debe estar vinculado al texto del encabezado y no al nombre de nodo .

XML a enlazar:

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

El código de código de XAML que carga XML a XDocument y lo enlaza a TreeView

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

Por lo tanto, en el marcado XAML estamos vinculando Nombre al encabezado de TreeViewItem.

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

Sin embargo, quiero vincularlo al atributo Título de la Sección, Bucle y Página en el Xml anterior. Leí que no es posible usar XPath mientras se vincula XDocument. Pero tiene que haber una manera de vincular el atributo Título al texto del encabezado de TreeViewItem. Intenté usar @Title,. [@ Title] etc. Pero ninguno parecía funcionar.

Este hilo en Los foros de MSDN tienen una discusión similar.

Cualquier puntero sería de gran ayuda.

¿Fue útil?

Solución

¡¡¡Hurra !!! Descubrí cómo enlazar XAttribute. No es intuitivo y no es fácilmente imaginable. Pero aquí es cómo se puede hacer.

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

Es difícil imaginar que el Título se pueda usar directamente entre llaves.

Más información en este enlace de MSDN

Otros consejos

Creo que todo lo que necesita hacer es crear un HierarchicalDataTemplate para cada tipo de nodo en su XML, cargue su xml en un XmlDataProvider , y luego vincule eso a TreeView. El televisor trabaja con el XDP para vincular los datos, y en algún punto de la línea se dan cuenta de qué HDT ha definido y hace coincidir su DataType con los nombres de los nodos en su XML. Es posible que tengas algunos problemas con el cambio de tu XPATH con los diferentes tipos de datos, pero mantenerlos flexibles es otra pregunta.

Por ejemplo, tengo una pequeña aplicación de prueba de expresiones regulares. Incluye un sistema de ayuda que es esencialmente todas las diferentes partes de expresiones regulares enumeradas en un árbol: Categorías y partes con descripciones, información sobre herramientas y otras cosas. Los datos sobre las partes se almacenan como un origen de datos xml. Desde su estado estático, acabo de crear un recurso estático con los recursos de la aplicación:

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

A continuación, creé Planchas de datos jerárquicos para cada uno tipo de nodo en los datos (de nuevo, todo esto está en los recursos de la aplicación):

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

Por último, simplemente vinculé el árbol al 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>

Y eso es todo lo que tienes que hacer. El TreeView y el XmlDataProvider se encargarán de encontrar y utilizar el correcto HDT's para los nodos correctos en los datos. La parte más difícil de todo esto es averiguar tus xpaths para el enlace. Puede ser un poco difícil, ya que si sus rutas son incorrectas, no obtendrá nada en el árbol y no habrá ningún error (hay formas de aumentar los informes de errores en el enlace de datos en WPF, pero esa es otra pregunta) .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top