Reputation: 8234
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
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