6

TreeView に任意の XML を表示し、ノードを展開したり折りたたんだりして、要素名と一連の属性とその値の両方を表示したいと考えています。HierarchicalDataTemplate でこれを行うことができると思います。

次のように、HierarchicalDataTemplate を使用して任意の XML要素とテキスト ノードを表示するためのヒントを見てきました。

  <Window.Resources>
    <HierarchicalDataTemplate x:Key="NodeTemplate">
      <TextBlock x:Name="tbName" Text="?" />
      <HierarchicalDataTemplate.ItemsSource>
        <Binding XPath="child::node()" />
      </HierarchicalDataTemplate.ItemsSource>
      <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=NodeType}" Value="Text">
          <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Value}"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
          <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Name}"/>
        </DataTrigger>
      </HierarchicalDataTemplate.Triggers>
    </HierarchicalDataTemplate>
    <XmlDataProvider x:Key="xmlDataProvider">
    </XmlDataProvider>
  </Window.Resources>
  ....

  <TreeView Name="treeView1"
          ItemsSource="{Binding Source={StaticResource xmlDataProvider}, XPath=*}"
          ItemTemplate= "{StaticResource NodeTemplate}"/>

これはうまくいきます。各要素の要素名とテキストが表示されます。しかし、私の XML は属性を使用して情報を運びます。スキーマは複雑で、正式な定義がないため、今のところ任意の XML として扱っています。

最も単純なドキュメントは次のようになります。

<c4soap name="GetVersionInfo" seq="" result="1">
  <versions>
    <version name="Director" 
             version="2.1.0.126418" 
             buildtype="" 
             builddate="Jun  1 2011" buildtime="14:52:43" />
    <version name="MediaManager" 
             version="2.1.0.126418" 
             buildtype="" 
             builddate="Jun  1 2011" 
             buildtime="14:36:17" />
  </versions>
</c4soap>

上記の HierarchicalDataTemplate 定義を使用して、表示用にこれを取得します。

ここに画像の説明を入力

私が欲しいものではありません。ノードごとに、要素名と一連の属性とその値の両方を表示したいと考えています。

私はこれを試しました:

  <Window.Resources>
    <HierarchicalDataTemplate x:Key="NodeTemplate">
      <WrapPanel
          Focusable="False">
        <TextBlock x:Name="tbName" Text="?" />
        <TextBlock x:Name="tbAttrs" Text="?" />
      </WrapPanel>
      <HierarchicalDataTemplate.ItemsSource>
        <Binding XPath="child::node()" />
      </HierarchicalDataTemplate.ItemsSource>
      <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=NodeType}" Value="Text">
          <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Value}"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
          <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Name}"/>
          <Setter TargetName="tbAttrs" Property="Text" Value="{Binding Path=Attributes}"/>
        </DataTrigger>
      </HierarchicalDataTemplate.Triggers>
    </HierarchicalDataTemplate>
    <XmlDataProvider x:Key="xmlDataProvider">
    </XmlDataProvider>
  </Window.Resources>

...ちょっと近づきますが、 Value="{Binding Path=Attributes}"結果としてTreeViewに「(コレクション)」が表示されます。

ここに画像の説明を入力

要素名に加えて、実際のすべての属性名と値を簡単に表示するにはどうすればよいですか?

4

2 に答える 2

9

ItemsControl次のように、テンプレートにを追加しました。

<Window.Resources>
  <SolidColorBrush x:Key="xmlValueBrush" Color="Blue" />
  <SolidColorBrush x:Key="xmAttributeBrush" Color="Red" />
  <SolidColorBrush x:Key="xmlTagBrush" Color="DarkMagenta" />
  <SolidColorBrush x:Key="xmlMarkBrush" Color="Blue" />
  <DataTemplate x:Key="attributeTemplate">
    <StackPanel Orientation="Horizontal"
                Margin="3,0,0,0"
                HorizontalAlignment="Center">
      <TextBlock Text="{Binding Path=Name}"
                 Foreground="{StaticResource xmAttributeBrush}"/>
      <TextBlock Text="=&quot;"
                 Foreground="{StaticResource xmlMarkBrush}"/>
      <TextBlock Text="{Binding Path=Value}"
                 Foreground="{StaticResource xmlValueBrush}"/>
      <TextBlock Text="&quot;"
                 Foreground="{StaticResource xmlMarkBrush}"/>
    </StackPanel>
  </DataTemplate>

  <HierarchicalDataTemplate x:Key="nodeTemplate">
    <StackPanel Orientation="Horizontal"
        Focusable="False">
      <TextBlock x:Name="tbName" Text="?" />
      <ItemsControl
          ItemTemplate="{StaticResource attributeTemplate}"
          ItemsSource="{Binding Path=Attributes}"
          HorizontalAlignment="Center">
        <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
          </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
      </ItemsControl>
    </StackPanel>
    <HierarchicalDataTemplate.ItemsSource>
      <Binding XPath="child::node()" />
    </HierarchicalDataTemplate.ItemsSource>
    <HierarchicalDataTemplate.Triggers>
      <DataTrigger Binding="{Binding Path=NodeType}" Value="Text">
        <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Value}"/>
      </DataTrigger>
      <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
        <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Name}"/>
      </DataTrigger>
    </HierarchicalDataTemplate.Triggers>
  </HierarchicalDataTemplate>
  <XmlDataProvider x:Key="xmlDataProvider">
  </XmlDataProvider>
</Window.Resources>

次のように、要素名一連の属性とその値が表示されます。

ここに画像の説明を入力

于 2011-10-03T14:39:03.793 に答える
4

また、さまざまなノード タイプに対してテンプレート セレクターを使用し、XPath node()|@* を使用してすべてのタイプのノードをループすることもできます。

<TreeView
    x:Name="TreeView"
    ItemsSource="{Binding}"
    ItemTemplateSelector="{DynamicResource ResourceKey=NodeTemplateSelector}">
    <TreeView.Resources>
        <HierarchicalDataTemplate x:Key="TextTemplate">
            <Grid>
                <uixml:TextInputControl DataContext="{Binding}" />
            </Grid>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate x:Key="AttributeTemplate">
            <Grid>
                <uixml:AttributeInputControl DataContext="{Binding}" />
            </Grid>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate x:Key="NodeTemplate" >
            <TextBlock Text="{Binding Path=Name}" />
            <HierarchicalDataTemplate.ItemsSource>
                <Binding XPath="child::node()|@*" />
            </HierarchicalDataTemplate.ItemsSource>
        </HierarchicalDataTemplate>
        <ui:XmlTemplateSelector
            x:Key="NodeTemplateSelector"
            NodeTemplate="{StaticResource NodeTemplate}"
            TextTemplate="{StaticResource TextTemplate}"
            AttributeTemplate="{StaticResource AttributeTemplate}" />
    </TreeView.Resources>
</TreeView>

と :

public class XmlTemplateSelector:DataTemplateSelector{
    public DataTemplate NodeTemplate { get; set; }
    public DataTemplate TextTemplate { get; set; }
    public DataTemplate AttributeTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container) {
        XmlNode node = (XmlNode)item;
        switch (node.NodeType) {
            case XmlNodeType.Attribute:
                return AttributeTemplate;
            case XmlNodeType.Element:
                return NodeTemplate;
            case XmlNodeType.Text:
                return TextTemplate;
        }
        throw new NotImplementedException(String.Format("not implemented for type {0}", node.NodeType));
    }
}
于 2011-10-06T23:36:53.883 に答える