4

WPF TreeViewにデータバインドする必要がある XML があります。ここで、XML は異なる構造を持つことができます。TreeView は、階層の任意の順列をロードするのに十分なデータバインド ジェネリックである必要があります。ただし、ノードのXAttribute ( Titleと呼ばれる) は、 nodename ではなくTreeViewItem のヘッダー テキストにデータ バインドする必要があります。

バインドする 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 の Section、Loop、および Page のTitle属性にバインドしたいと考えています。XDocument のバインド中に XPath を使用することはできないと読みました。ただし、 Title属性を TreeViewItem のヘッダー テキストにバインドする方法が必要です。@Title、.[@Title] などを使用してみましたが、どれも機能していないようです。

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

どんな指針も大いに役に立ちます。

4

2 に答える 2

12

万歳!!! XAttribute をバインドする方法を理解しました。それは直感的ではなく、容易に想像できるものではありません。しかし、ここにそれを行う方法があります。

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

Title を角括弧で直接使用できるとは考えにくいです。

もっと@このMSDNリンク

于 2008-10-26T17:12:18.883 に答える
2

XML内のノードタイプごとにHierarchicalDataTemplateを作成し、xmlをXmlDataProviderにロードして、それを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のデータバインディングでエラーレポートを増やす方法はありますが、それは別の質問です)。 。

于 2008-10-26T16:54:40.183 に答える