illegal-immigrant
illegal-immigrant

Reputation: 8234

WPF treeview datatemplate

Let's say I have something like this:

public class TopicFolder
    {
        #region Constants and Fields

        private readonly List<TopicInfo> folderContent;

        private readonly List<TopicFolder> subFolders;

        #endregion

...
    }

How do I implement a data template for such type? Currently I have:

<HierarchicalDataTemplate DataType="{x:Type local:TopicFolder}" ItemsSource="{Binding SubFolders}" >
            <TextBlock Text="{Binding Name}"/>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type local:TopicInfo}" ItemsSource="{Binding FolderContent}">
            <TextBlock Text="{Binding TopicName}"/>
        </HierarchicalDataTemplate>

But this does not show any folder content. It seems that second's template DataType should be local:TopicFolder, but this is not allowed by WPF.

Any suggestions?

UPD : TreeView is bound to ObservableCollection<TopicFolder> this way:

ItemsSource="{Binding Path=Folders}"

P.S: It is definitely not a private/public/properties problem. I have corresponding public properties for posted fields. No binding errors in output, it is just not showing any FolderContent items.

Upvotes: 0

Views: 1974

Answers (1)

brunnerh
brunnerh

Reputation: 184516

Edit:

To show both sub-folders and content one can either use a MultiBinding or if you don't mind that folders and content can appear in a certain order I'd suggest using the composite pattern, for that you remove your SubFolders and FolderContent and replace it with a collection of objects which implement the composite interface (read the wiki article).

Creating a property to merge the two collections, so you can bind to it, is bad practice.

Example for composite pattern:

public interface ITopicComposite
{
    // <Methods and properties folder and content have in common (e.g. a title)>

    // They should be meaningful so you can just pick a child
    // out of a folder and for example use a method without the
    // need to check if it's another folder or some content.
}

public class TopicFolder : ITopicComposite
{
    private readonly ObservableCollection<ITopicComposite> children = new ObservableCollection<ITopicComposite>();
    public ObservableCollection<ITopicComposite> Children
    {
        get { return children; }
    }

    //...
}

public class TopicInfo : ITopicComposite
{
    //...
}

Upvotes: 1

Related Questions