Xml AttributeをTreeviewノードにバインドし、XDocumentをWPF Treeviewにデータバインドする方法

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

質問

WPF TreeView にデータバインドする必要があるXMLがあります。ここで、XMLは異なる構造を持つことができます。 TreeViewは、階層の順列をロードするのに十分な汎用データバインドである必要があります。ただし、ノード上の XAttribute Title と呼ばれる)はTreeViewItemの header text にデータバインドされ、ノード名ではなく

バインドされる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>

XMLをXDocumentにロードしてTreeViewにバインドするXAMLのコードビハインド

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のセクション、ループ、ページのタイトル属性にバインドします。 XDocumentのバインド中にXPathを使用することはできないと読みました。ただし、 Title 属性をTreeViewItemのヘッダーテキストにバインドする方法が必要です。 @Title、。[@ Title]などを使用してみました。しかし、どれも機能していないようです。

このスレッドMSDNフォーラムにも同様の議論があります。

任意のポインターが非常に役立ちます。

役に立ちましたか?

解決

ハラー!!! XAttributeをバインドする方法を見つけました。直感的ではなく、簡単に想像もできません。しかし、ここでそれを行う方法があります。

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

Titleを角括弧で直接使用できるとは想像しにくいです。

その他の@このMSDNリンク

他のヒント

必要なのは、 HierarchicalDataTemplateを作成することだけです XMLの各ノードタイプについて、XMLをにロードしますXmlDataProvider を選択し、 that をTreeViewにバインドします。 TVはXDPと連携してデータをバインドし、線に沿ってどこかで定義したHDTを見つけ出し、そのDataTypeをXML内のノードの名前に一致させます。さまざまなタイプのデータでXPATHを変更する際に問題が発生する可能性がありますが、それらを柔軟に保つことは別の質問です。

たとえば、小さな正規表現テストアプリがあります。基本的にツリーにリストされているすべての異なる正規表現パーツであるヘルプシステムが含まれています:カテゴリ、説明、ツールチップ、およびその他のパーツ。パーツに関するデータは、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>

次に、 HierarchicalDataTemplates を作成しましたデータのノードタイプ(これもすべてアプリケーションのリソースにあります):

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

そして、あなたがしなければならないのはそれだけです。 TreeViewと XmlDataProvider は、正しいものを見つけて使用する処理を行います。データ内の正しいノードの HDT 。これらすべての中で最も難しい部分は、バインディングのためにxpathを見つけることです。パスが正しくない場合、ツリーには何も表示されず、エラーも発生しないため、少し注意が必要です(WPFのデータバインディングでエラー報告を増やす方法はありますが、それは別の質問です) 。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top