5

短いバージョン:

TreeViewさまざまな種類の項目の階層 ( ) を表示する必要がありますが、Silverlight でこれをきれいに行う方法がわかりません。HierarchicalDataTemplateWPF では、型に基づいてテンプレート ( ) を定義するのは簡単ですが、この機能は Silverlight では使用できません。Silverlight では、特定のノードのすべての子に同じテンプレートを適用する必要があるようです。そのため、考えられるすべてのタイプのノードを処理する 1 つのモンスター テンプレートが、すべてのノードに適用されることになります。

長いバージョン (例):

より具体的な (ただし不自然な) 例を示すために、さまざまなフォルダー内のアーカイブのツリービューを考えてみましょう。各アーカイブには、写真、曲、およびその他のアーカイブを含めることができます。各フォルダーには、複数のサブフォルダーとアーカイブが含まれる場合があります。

|-Folder
  |-Folder
    |-Folder
      |-Archive
        | Photo1
        | Photo2
        | Song1
        | Song2
        |-Archive
          | Photo1
          | Song1
  |-Archive
    | Photo1
    | Photo2
    | Photo3

ツリーの各タイプ (フォルダ、アーカイブ、写真、曲) は、異なる方法で表示されます。明らかな解決策は、HierarchicalDataTemplate表示するアイテムの種類ごとに を作成することのようです。残念ながら、ノード ( ) のすべての子に対して単一のテンプレート タイプを指定する必要があるように思われるため、これを行う良い方法が見つかりませんItemsSource={Binding ...}, ItemsTemplate={StaticResource TemplateForAllChildren}

この要件により、テンプレートは雪だるま式になります... アーカイブには、写真、曲、およびアーカイブを子として含めることができます。1 つのテンプレートをすべての子に適用する必要があるため、その 1 つのテンプレートで写真、曲、およびアーカイブを処理できる必要があります。同様に、フォルダのテンプレートはフォルダとアーカイブを処理できる必要があり、アーカイブ テンプレートには写真と歌が含まれているため、すべてが写真、曲、アーカイブ、およびフォルダを処理できる 1 つの巨大なテンプレートになります。より多くのタイプが追加されると、それらも 1 つの巨大なテンプレートにまとめられます。

さまざまなタイプがツリーに追加されるため、1 つの巨大なテンプレート (および関連するノード ビューモデル) を蓄積することなく、これをきれいに行う方法はありますか?

ありがとう!

明確化:

これまでの回答に感謝しますが、元の問題に戻るだけかもしれません。私は答えを誤解しているかもしれません。

以下を示す TreeView を検討してください。

曲の場合: アーティスト/タイトルを含むスクロール テキスト ボックスと再生ボタン

写真の場合: サムネイル画像と星評価コントロール

アーカイブの場合: 圧縮を示すプログレス バーを含むアーカイブ イメージ

フォルダの場合: フォルダ名を示すプレーン ラベル

私が知る限り、これを実現する唯一の方法は、スクロール テキスト ボックス、再生ボタン、サムネイル ビューア、スター コントロール、画像コントロール、進行状況バー、およびラベルを含む 1 つの巨大な HierarchicalDataTemplate を用意することです。次に、ノードに実際に適用される 1 つまたは 2 つのコントロールを除くすべてを選択的に非表示にします。

WPF では、テンプレートをノード タイプに関連付けることができたので、各ノードは適切なテンプレートを使用できました。Silverlightでこれを行う方法があるかどうか疑問に思っています。

再度、感謝します!

4

3 に答える 3

3

では、このようなことを試してみませんか?

階層データ テンプレート

<sdk:HierarchicalDataTemplate x:Key="ChildTemplate" ItemsSource="{Binding Path=SubItems}">
    <TextBlock Text="{Binding Name}" Foreground="{Binding ForegroundColor}" />
</sdk:HierarchicalDataTemplate>
<sdk:HierarchicalDataTemplate x:Key="FilesDataTemplate" ItemsSource="{Binding Path=SubItems}" ItemTemplate="{StaticResource ChildTemplate}">
    <TextBlock Text="{Binding Name}" Foreground="{Binding ForegroundColor}" />
</sdk:HierarchicalDataTemplate>

ノード クラス

public class Node
{
    public string Name { get; set; }
    public ObservableCollection<Node> SubItems { get; set; }
    public SolidColorBrush ForegroundColor { get; set; }

    public Node(string name, Color foregroundColor, params Node[] items)
    {
        this.Name = name;
        this.SubItems = new ObservableCollection<Node>(items);
        this.ForegroundColor = new SolidColorBrush(foregroundColor);
    }
}

サンプルデータ

public partial class MainPage : UserControl
{
    public ObservableCollection<Node> Nodes { get; set; }

    public MainPage()
    {
        InitializeComponent();

        this.Nodes = new Node("Root", Colors.Blue,
                             new Node("File1", Colors.Black),
                             new Node("File2", Colors.Black),
                             new Node("Archive1", Colors.Red,
                                        new Node("File3", Colors.Magenta),
                                        new Node("File4", Colors.Magenta))
                             ).SubItems;

        treeView1.DataContext = this;
    }
}

あなたの場合、サブクラスの各タイプ(Archive、Photo、Music)によって実装されるスタイリングノード(ForegroundColorなど)のすべてのプロパティを持つインターフェイス(たとえばINode)が役立つ可能性があります。

お役に立てれば。

于 2010-11-30T21:19:33.240 に答える
0

これと同様の問題があり、複数のノードタイプを持つTreeViewがあり、ノードタイプに基づいて別のテンプレートを選択できるようにしたいと考えていました。

結局、私はTemplateChooserに出くわし、それをHierarchicalDataTemplatesと組み合わせて使用​​しました。(コードがVBにあるという事実を許してください)

Public MustInherit Class TemplateSelector
    Inherits ContentControl

    Public MustOverride Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate

    Protected Overrides Sub OnContentChanged(oldContent As Object, newContent As Object)
        MyBase.OnContentChanged(oldContent, newContent)

        ContentTemplate = SelectTemplate(newContent, Me)
    End Sub

End Class

次に、ツリービュー用の特定のテンプレートセレクターを作成しました。これにより、オブジェクトタイプに基づいて異なるデータテンプレートが公開されました。

Public Class NodeTypeTemplateSelector
    Inherits TemplateSelector

    Public Property NodeType1Template As DataTemplate
    Public Property NodeType2Template As DataTemplate
    Public Property NodeType3Template As DataTemplate

    Public Overrides Function SelectTemplate(item As Object, container As System.Windows.DependencyObject) As System.Windows.DataTemplate

        If item.GetType.Equals(GetType(NodeType1VM)) Then
            Return NodeType1Template
        ElseIf item.GetType.Equals(GetType(NodeType2VM)) Then
            Return NodeType2Template
        ElseIf item.GetType.Equals(GetType(NodeType3VM)) Then
            Return NodeType3Template
        Else

            Return Nothing
        End If

    End Function
End Class

これが、TemplateSelectorを実装する私が使用したHierarchicalDataTemplateのXAMLです。

<sdk:HierarchicalDataTemplate x:Key="SelectingTemplate" ItemsSource="{Binding children, Mode=OneWay}">
            <local:NodeTypeTemplateSelector Content="{Binding}"
                                            NodeType1Template="{StaticResource MyNodeType1HierarchicalTemplate}"
                                            NodeType2Template="{StaticResource MyNodeType2HierarchicalTemplate}"
                                            NodeType3Template="{StaticResource MyNodeType3HierarchicalTemplate}"
                                           />
        </sdk:HierarchicalDataTemplate>

もちろん、MynodeType1HierarchicalTemplateなど、さまざまなタイプの階層データテンプレートをいくつか作成しました。

于 2013-02-21T11:35:40.777 に答える
0

Silverlight 5 では、暗黙的なデータ テンプレートを使用してこれを解決することもできます。

<UserControl.Resources>
    <sdk:HierarchicalDataTemplate x:Key="treeNodeTemplate" 
                                  ItemsSource="{Binding Children}">
        <ContentControl Content="{Binding}">
            <ContentControl.Resources>
                <DataTemplate DataType="ViewModels:Folder">
                    <TextBlock Text="{Binding FolderName}" />
                </DataTemplate>
                <DataTemplate DataType="ViewModels:Song">
                    <Image Source="{Binding PictureSource}" />
                </DataTemplate>
                ...
            </ContentControl.Resources>
        </ContentControl>
    </sdk:HierarchicalDataTemplate>
</UserControl.Resources>

<sdk:TreeView ItemsSource="{Binding Roots, Mode=OneWay}"
              ItemTemplate="{StaticResource treeNodeTemplate}"/>

Silverlight 5 は、適切な HierarchicalDataTemplate 自体の自動選択をまだサポートしていないため、ターゲット タイプに応じて、すべてのタイプのノードに対して単一の HierarchicalDataTemplate を使用します。したがって、各ノード ビュー モデルに同じ Children メンバーを含める必要があります。

于 2012-11-30T15:34:42.333 に答える