Como ligar atributo XML a TreeView nós, enquanto ligação de dados XDocument para WPF Treeview

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

Pergunta

Eu tenho um XML que precisa ser databound a um WPF TreeView . Aqui, o XML pode ter estrutura diferente. O TreeView deve ser suficiente genérico databound para carregar qualquer permutação de hierarquia. No entanto, um XAttribute nos nós (chamado Título ) deve ser databound ao texto cabeçalho do TreeViewItem e não o nome do nó .

XML em ficar vinculado:

<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 do XAML que carrega XML para XDocument e liga-o TreeView

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

Assim, na marcação XAML que são vinculativas nome para o cabeceamento de TreeViewItem.

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

No entanto, quero vinculá-lo a Título atributo da Seção, Loop e página no XML acima. Eu li que não é possível usar XPath enquanto a ligação XDocument. Mas tem que haver uma maneira de vincular o Título atributo para texto de cabeçalho do TreeViewItem. Eu tentei usar @Title,. [@ Título] etc. Mas nada parecia funcionar.

Esta discussão em MSDN Fóruns tem uma discussão semelhante.

Os ponteiros seria muito útil.

Foi útil?

Solução

Hurra !!! Eu descobri como ligar XAttribute. Não é intuitiva e não é facilmente imaginável. Mas aqui é como isso pode ser feito.

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

É difícil imaginar que o título pode ser directamente utilizado em colchetes.

Mais @ este link MSDN

Outras dicas

Eu acho que tudo o que você precisa fazer é criar um HierarchicalDataTemplate para cada tipo de nó no XML, carregar o xml-lo em um XmlDataProvider , e depois ligam que para o TreeView. A TV funciona com o XDP aos dados de vinculação, e em algum lugar ao longo da linha que descobrir o que HDTs ter definido e combinar seu tipo de dados para os nomes dos nós no XML. Você pode ter alguns problemas com seus XPATHs mudando com os diferentes tipos de dados, mas mantendo os flexível é outra questão.

Por exemplo, eu tenho um aplicativo de teste regex pouco. Ele inclui um sistema de ajuda que é essencialmente todas as diferentes partes regex listadas em uma árvore: Categorias e peças com descrições, dicas de ferramentas, e outras coisas. Os dados sobre as partes é armazenado como uma fonte de dados XML. Desde a sua estática, Acabei de criar um recurso estático com recursos do aplicativo:

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

Em seguida, eu criei HierarchicalDataTemplates para cada tipo de nó nos dados (novamente, tudo isso é em recursos do aplicativo):

<!-- 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 fim, eu só ligada a árvore para o 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>

E isso é tudo que você precisa fazer. O TreeView eo XmlDataProvider vai cuidar de encontrar e utilizar a correta do HDT para os nós corretos na dados. A parte mais difícil de tudo isso é descobrir seus XPaths para a ligação. Ele pode ficar um pouco complicado, como se os seus caminhos estiverem incorretos, você vai acabar recebendo nada na árvore e não haverá quaisquer erros (existem maneiras para melhorar a comunicação erro na ligação de dados no WPF, mas isso é outra questão) .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top