WPF TreeView ObservableCollection notifying sample code - c#

I'm trying to write a C# WPF application and I'm stuck with the TreeView and ObservableCollection.
This is my TreeView Items.
| Root
--- SubItem
------ SubItem
| Root
--- SubItem
------ SubItem
---------- SubItem
I'm modifyng this items from other window and I need to update this treeview without re-loading all items. I've made my search and I found ObservableCollection. But I can't understand how to use ObservableCollection and notify changes and update this list.
Can you give me some sample code or help me with doing that?

Here is a good example to Implement Simplifying the WPF TreeView by Using the ViewModel Pattern.
This is just another sample,
Your Model:
public interface IFolder
{
string FullPath { get; }
string FolderLabel { get; }
ObservableCollection<IFolder> Folders { get; }
}
Your ViewModel:
class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
m_folders = new ObservableCollection<IFolder>();
//add Root items
Folders.Add(new Folder { FolderLabel = "Dummy1", FullPath = #"C:\dummy1" });
Folders.Add(new Folder { FolderLabel = "Dummy2", FullPath = #"C:\dummy2" });
Folders.Add(new Folder { FolderLabel = "Dummy3", FullPath = #"C:\dummy3" });
Folders.Add(new Folder { FolderLabel = "Dummy4", FullPath = #"C:\dummy4" });
//add sub items
Folders[0].Folders.Add(new Folder { FolderLabel = "Dummy11", FullPath = #"C:\dummy11" });
Folders[0].Folders.Add(new Folder { FolderLabel = "Dummy12", FullPath = #"C:\dummy12" });
Folders[0].Folders.Add(new Folder { FolderLabel = "Dummy13", FullPath = #"C:\dummy13" });
Folders[0].Folders.Add(new Folder { FolderLabel = "Dummy14", FullPath = #"C:\dummy14" });
}
public string TEST { get; set; }
private ObservableCollection<IFolder> m_folders;
public ObservableCollection<IFolder> Folders
{
get { return m_folders; }
set
{
m_folders = value;
NotifiyPropertyChanged("Folders");
}
}
void NotifiyPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
public event PropertyChangedEventHandler PropertyChanged;
}
In xaml:
<TextBlock Text="Simple root binding" Foreground="Red" Margin="10,10,0,0" />
<TreeView ItemsSource="{Binding Folders}" Margin="10">
<TreeView.ItemTemplate>
<DataTemplate>
<TreeViewItem Header="{Binding FolderLabel}"/>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Full code

Related

Why TreeView doesn't list my subdirectories? [duplicate]

I am trying to get my head around Heirarchical DataTemplates and TreeViews in WPF and am having some trouble.
I have created an app with only a TreeView on the form as below and defined HierarchicalDataTemplate's for both a Directory object and a File object I then Bind the TreeView to the Directories property (ObservableCollection) of my model.
<Grid>
<Grid.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Directory}" ItemsSource ="{Binding Directories}">
<TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:File}" ItemsSource ="{Binding Files}">
<TextBlock Text="{Binding Path=FileName}"/>
</HierarchicalDataTemplate>
</Grid.Resources>
<TreeView Margin="12,12,0,12" Name="treeView1" HorizontalAlignment="Left" Width="204" >
<TreeViewItem ItemsSource="{Binding Directories}" Header="Folder Structure" />
</TreeView>
</Grid>
This works in that in the TreeView I see my directories and it recursively displays all sub directories, but what I want to see is Directories and Files! I've checked the model and it definately has files in some of the sub directories but I can't see them in the tree.
I'm not sure if it is my template that is the problem or my model so I have included them all! :-)
Thanks
OneShot
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private MainWindowViewModel _vm;
public MainWindowViewModel VM
{
set
{
_vm = value;
this.DataContext = _vm;
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var d = new Directory() { Name = "temp" };
recurseDir("c:\\temp", ref d);
VM = new MainWindowViewModel( new List<Directory>() { d } );
}
private void recurseDir(string path, ref Directory dir)
{
var files = System.IO.Directory.GetFiles(path);
var dirs = System.IO.Directory.GetDirectories(path);
dir.Name = path.Substring(path.LastIndexOf("\\")+1);
for (int i = 0; i < files.Length; i++)
{
var fi = new FileInfo(files[i]);
dir.Files.Add(new File() {
FileName = System.IO.Path.GetFileName(files[i]),
DirectoryPath = System.IO.Path.GetDirectoryName(files[i]),
Size = fi.Length,
Extension= System.IO.Path.GetExtension(files[i])
});
}
for (int i = 0; i < dirs.Length; i++)
{
var d = new Directory() { Name = dirs[i].Substring(dirs[i].LastIndexOf("\\")+1) };
recurseDir(dirs[i], ref d);
dir.Directories.Add(d);
}
}
}
-
public class MainWindowViewModel
: DependencyObject
{
public MainWindowViewModel(List<Directory> Dirs)
{
this.Directories = new ObservableCollection<Directory>( Dirs);
}
public ObservableCollection<Directory> Directories
{
get { return (ObservableCollection<Directory>)GetValue(DirectoriesProperty); }
set { SetValue(DirectoriesProperty, value); }
}
public static readonly DependencyProperty DirectoriesProperty =
DependencyProperty.Register("Directories", typeof(ObservableCollection<Directory>), typeof(MainWindowViewModel), new UIPropertyMetadata(null));
public Directory BaseDir
{
get { return (Directory)GetValue(BaseDirProperty); }
set { SetValue(BaseDirProperty, value); }
}
public static readonly DependencyProperty BaseDirProperty =
DependencyProperty.Register("BaseDir", typeof(Directory), typeof(MainWindowViewModel), new UIPropertyMetadata(null));
}
-
public class Directory
{
public Directory()
{
Files = new List<File>();
Directories = new List<Directory>();
}
public List<File> Files { get; private set; }
public List<Directory> Directories { get; private set; }
public string Name { get; set; }
public int FileCount
{
get
{
return Files.Count;
}
}
public int DirectoryCount
{
get
{
return Directories.Count;
}
}
public override string ToString()
{
return Name;
}
}
-
public class File
{
public string DirectoryPath { get; set; }
public string FileName { get; set; }
public string Extension { get; set; }
public double Size { get; set; }
public string FullPath
{
get
{
return System.IO.Path.Combine(DirectoryPath, FileName);
}
}
public override string ToString()
{
return FileName;
}
}
Take a look at this again:
<HierarchicalDataTemplate DataType="{x:Type local:Directory}" ItemsSource ="{Binding Directories}">
<TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:File}" ItemsSource ="{Binding Files}">
<TextBlock Text="{Binding Path=FileName}"/>
</HierarchicalDataTemplate>
What you're saying is that if you encounter an object of type File, display it with a text block and get its children from a property Files under the File. What you really want is for the Files to show up under each Directory, so you should create a new property that exposes both Directories and Files:
public class Directory
{
//...
public IEnumerable<Object> Members
{
get
{
foreach (var directory in Directories)
yield return directory;
foreach (var file in Files)
yield return file;
}
}
//...
}
and then your template becomes:
<HierarchicalDataTemplate DataType="{x:Type local:Directory}" ItemsSource ="{Binding Members}">
<TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:File}">
<TextBlock Text="{Binding Path=FileName}"/>
</DataTemplate>
UPDATE:
Actually, the above is not sufficient if you want to receive collection changed notifications for the Members. If that's the case, I recommend creating a new ObservableCollection and adding Directory and File entries to it in parallel to adding to the Files and Directories collections.
Alternately, you may wish to reconsider how you store your information and put everything in a single collection. The other lists are then simply filtered views of the main collection.

WPF TreeView with HierarchicalDataTemplate and ObservableCollection containing Children

I'm trying to get this to work but unfortunately I have no idea what I'm doing wrong! I've looked into every uestion asked so far containing TreeView and the HierarchicalDataTemplate.
Here's the problem: I have a TreeView and would like to show the folder structure with all SubFolders and Files in it. To do so I created a class with the necessary Items:
public class FolderItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public FolderItem()
{
Files = new ObservableCollection<FileItem>();
SubFolders = new ObservableCollection<FolderItem>();
}
#region:PrivateVariables
private DirectoryInfo _Info;
private ObservableCollection<FileItem> _Files;
private ObservableCollection<FolderItem> _SubFolders;
#endregion
public DirectoryInfo Info
{
get { return _Info; }
set
{
_Info = value;
OnPropertyChanged("Info");
}
}
public ObservableCollection<FileItem> Files
{
get { return _Files; }
set
{
_Files = value;
OnPropertyChanged("Files");
}
}
public ObservableCollection<FolderItem> SubFolders
{
get { return _SubFolders; }
set
{
_SubFolders = value;
OnPropertyChanged("SubFolders");
}
}
}
public class FileItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#region:PrivateVariables
private FileInfo _Info;
#endregion
public FileInfo Info
{
get { return _Info; }
set
{
_Info = value;
OnPropertyChanged("Info");
}
}
}
In the code I now loop through all Folders and Files and the ObservableCollection folders now shows the correct data! The code I use looks like this:
public void StartExtraction(string sPath)
{
if (Directory.Exists(sPath))
{
FolderItem newFolder = new FolderItem();
newFolder.Info = new DirectoryInfo(sPath);
GetFileCount(sPath, newFolder);
Application.Current.Dispatcher.Invoke((Action)delegate ()
{
ViewModel_ZVLB.folders.Add(newFolder);
});
}
}
public void GetFileCount(string sPath, FolderItem actualFolder)
{
if (Directory.Exists(sPath))
{
foreach (string fileName in Directory.GetFiles(sPath))
{
FileItem newFile = new FileItem();
newFile.Info = new FileInfo(fileName);
actualFolder.Files.Add(newFile);
}
foreach (string subFolder in Directory.GetDirectories(sPath))
{
FolderItem newSubFolder = new FolderItem();
newSubFolder.Info = new DirectoryInfo(subFolder);
actualFolder.SubFolders.Add(newSubFolder);
GetFileCount(subFolder, newSubFolder);
}
}
}
With this OC I go to the XAML and tried a lot to show the Data:
<TreeView ItemsSource="{Binding folders}">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding folders}" DataType="{x:Type local:FolderItem}">
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Info.Name}" />
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Info.FullName}" FontSize="16" FontWeight="Bold" />
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Even with another HierarchicalDataTemplate it won't work.
Is there anything I did wrong? Or is it just not working with ObservableCollections?
Intereisting is also that after the Update of Visual Studio 2017 a new Error appeared: As "folders" for Tpye "ViewModel_ZVLB" a instancemenber is expected! (translated from German)
Has this something to do with my problem?
Thanks for your help!
In my opinion, if you want to work with Treeviews, it is easier to use only one Observablecollection for the children.
First I create a generic class for each element of your Tree. The Folder and File classes inherits from it.
public class TreeItem: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class FolderItem:TreeItem
{
public FolderItem()
{
Elems = new ObservableCollection<TreeItem>();
}
#region:PrivateVariables
private DirectoryInfo _Info;
private ObservableCollection<TreeItem> _Elems;
#endregion
public DirectoryInfo Info
{
get { return _Info; }
set
{
_Info = value;
OnPropertyChanged("Info");
}
}
public ObservableCollection<TreeItem> Elems
{
get { return _Elems; }
set
{
_Elems = value;
OnPropertyChanged("Elems");
}
}
}
public class FileItem : TreeItem
{
#region:PrivateVariables
private FileInfo _Info;
#endregion
public FileInfo Info
{
get { return _Info; }
set
{
_Info = value;
OnPropertyChanged("Info");
}
}
}
Here is the XAML code:
<TreeView ItemsSource="{Binding folders}">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Elems}" DataType="{x:Type local:FolderItem}">
<TextBlock Text="{Binding Info.Name}" FontWeight="Bold"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:FileItem}">
<TextBlock Text="{Binding Info.Name}" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
Of course you need to update your filling function:
public void GetFileCount(string sPath, FolderItem actualFolder)
{
if (Directory.Exists(sPath))
{
foreach (string fileName in Directory.GetFiles(sPath))
{
FileItem newFile = new FileItem();
newFile.Info = new FileInfo(fileName);
actualFolder.Elems.Add(newFile);
}
foreach (string subFolder in Directory.GetDirectories(sPath))
{
FolderItem newSubFolder = new FolderItem();
newSubFolder.Info = new DirectoryInfo(subFolder);
actualFolder.Elems.Add(newSubFolder);
GetFileCount(subFolder, newSubFolder);
}
}
}

TreeView display hierarchical data

I have the following two model-classes:
public class FileItem : NotifyBase
{
public FileItem(string fullPath)
{
FullPath = fullPath;
}
public string FullPath
{
get { return Get<string>(); }
set
{
Set(value);
OnPropertyChanged("FileName");
OnPropertyChanged("Directory");
}
}
public string Directory
{
get { return Path.GetDirectoryName(FullPath); }
}
public string FileName
{
get { return Path.GetFileName(FullPath); }
}
}
and
public class Directory : NotifyBase
{
public Directory(string fullPath)
{
FullPath = fullPath;
Files = new ObservableCollection<FileItem>();
Directories = new ObservableCollection<Directory>();
}
public ObservableCollection<FileItem> Files
{
get { return Get<ObservableCollection<FileItem>>(); }
set { Set(value); }
}
public ObservableCollection<Directory> Directories
{
get { return Get<ObservableCollection<Directory>>(); }
set { Set(value); }
}
public string FullPath
{
get { return Get<string>(); }
set
{
Set(value);
OnPropertyChanged("DirectoryName");
}
}
public string DirectoryName
{
get
{
string[] directoryNameSplit = FullPath.Split(new[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
if (directoryNameSplit.Length > 0)
{
return directoryNameSplit[directoryNameSplit.Length - 1];
}
return "UNKNOWN";
}
}
}
The class NotifyBase is just an implementation of INotifyPropertyChanged.
I load the data from the filesystem and so I have a hierarchy of objects. Now I want to display that hierarchy of Directorys and FileItems in the View as a TreeView.
In the ViewModel I have an ObservableCollection<Directory> called Directories with the root nodes.
My View is:
<TreeView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5" x:Name="tv"
ItemsSource="{Binding Directories, UpdateSourceTrigger=PropertyChanged}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type model:Directory}" ItemsSource="{Binding Directories}">
<Label Content="{Binding Path=DirectoryName}" VerticalAlignment="Center"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type model:FileItem}">
<Label Content="{Binding FileName}" VerticalAlignment="Center" Background="Red"/>
</DataTemplate>
</TreeView.Resources>
</TreeView>
All folders are displayed perfect, but I don't see any FileItems and I don't know why. What I'm doing wrong here?
Because you have your two collections separate, and you are not binding to Files anywhere.
Instead of two collections, have one collection of two types.

Cannot get Silverlight HierarchicalDataTemplate to display IsolatedStorage folders

This is my first foray into Hierarchical data and am having a bit of a problem.
In Silverlight 4, I am trying to get a list of isolated storage folders to display in a TreeView. Nothing displays at all. My Treeview is completely blank. What am I missing? I am getting data and it is correct.
Any help would be appreciated.
XAML
<sdk:TreeView x:Name="FolderTreeView" Grid.Column="0" Margin="0,0,3,0" ItemsSource="{Binding _Folders}">
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Folders}">
<TextBlock Margin="0" Text="{Binding Name, Mode=OneWay}"/>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
</sdk:TreeView>
CS
internal class Folder
{
public Folder() { Folders = new List<Folder>(); }
public string Name { get; set; }
public List<Folder> Folders { get; set; }
}
private List<Folder> _Folders = new List<Folder>();
public OpenFileDialog()
{
InitializeComponent();
ifs = IsolatedStorageFile.GetUserStoreForApplication();
var folder = new Folder
{
Name = "Root",
Folders = (from c in ifs.GetDirectoryNames()
select new Folder
{
Name = c,
Folders = LoadFolders(c)
}).ToList()
};
_Folders.Add(folder);
FolderTreeView.DataContext = new { _Folders };
}
private List<Folder>LoadFolders(string folderName)
{
if(folderName == null)
return null;
return (from c in ifs.GetDirectoryNames(folderName + "\\*.*")
select new Folder
{
Name = c,
Folders = LoadFolders(c)
}).ToList();
}
Thanks
A few things
<sdk:TreeView x:Name="FolderTreeView" Grid.Column="0" Margin="0,0,3,0"
ItemsSource="{Binding _Folders}">
you can't bind to private members.
You need to use ObservableCollections instead of Lists. The binding manager effectively listens for the CollectionChanged events fired by ObservableCollection and notifies the bound controls.
You'll want to implement INotifyPropertyChanged and raise PropertyChanged notifications in your property setters.
Finally, have you set the DataContext for the Treeview?
Also, look in your Output debug window for errors relating to binding.
Edit, ok try:
FolderTreeView.DataContext = this;
and wrap _Folders in a property
public ObservableCollection <Folder> Folders
{
get
{
return _Folders;
}
set
{
_Folders = value;
OnPropertyChanged("Folders");
}
}
change your binding to
<sdk:TreeView x:Name="FolderTreeView" Grid.Column="0" Margin="0,0,3,0"
ItemsSource="{Binding Folders}">
I've changed things quite a bit,
public class Folder : INotifyPropertyChanged
{
public Folder(string folderName)
{
Name = folderName;
Folders = new ObservableCollection<Folder>();
var _ifs = IsolatedStorageFile.GetUserStoreForApplication();
if (folderName != null)
{
Folders = new ObservableCollection<Folder>(
(from c in _ifs.GetDirectoryNames(folderName + "\\*.*")
select new Folder(folderName + "\\" + c)
));
}
else
{
Folders = new ObservableCollection<Folder>(
(from c in _ifs.GetDirectoryNames()
select new Folder(folderName + "\\" + c)
));
}
}
public string Name { get; set; }
private ObservableCollection<Folder> _Folders;
public ObservableCollection<Folder> Folders
{
get { return _Folders; }
set { _Folders = value; OnPropertyChanged("RootFolder"); }
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
public partial class OpenFileDialog : UserControl
{
public OpenFileDialog()
{
InitializeComponent();
RootFolder = new Folder (null);
RootFolders = new ObservableCollection<Folder>();
RootFolders.Add(RootFolder);
FolderTreeView.DataContext = this;
}
private Folder _RootFolder;
public Folder RootFolder
{
get { return _RootFolder; }
set { _RootFolder = value; }
}
private ObservableCollection<Folder> _RootFolders;
public ObservableCollection<Folder> RootFolders
{
get { return _RootFolders; }
set { _RootFolders = value; }
}
}
xaml
<sdk:TreeView x:Name="FolderTreeView" Margin="0,0,3,0" ItemsSource="{Binding RootFolders}">
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Folders}">
<StackPanel>
<TextBlock Margin="0" Text="{Binding Name, Mode=OneWay}"/>
</StackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
</sdk:TreeView>
Ok...problem solved. Don't understand why though.
I had the ChildWindow set as internal scope instead of public scope because I didn't want the window itself to be viewed external of my Silverlight class library. If anyone can answer why this would stop Hierarchical data binding but not standard data binding I would like to know.

WPF: Problem with TreeView databinding

I have a tree view defined as follows:
<HierarchicalDataTemplate x:Key="ChildTemplate"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding TagName, Mode=OneWay}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="NavigationHeaderTemplate"
ItemsSource="{Binding Children}"
ItemTemplate="{StaticResource ChildTemplate}">
<StackPanel Orientation="Horizontal" Margin="0">
<Image Source="{Binding Image}" Height="16" Width="16"></Image>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<TreeView Grid.Row="0" Grid.Column="0" Margin="0"
FlowDirection="LeftToRight"
ItemTemplate="{StaticResource NavigationHeaderTemplate}"
Name="TreeView2">
</TreeView>
The data binding is:
public class ViewTag : INotifyPropertyChanged
{
private string _tagName;
public string TagName
{
get { return _tagName; }
set
{
_tagName = value;
PropertyChanged(this, new PropertyChangedEventArgs("Tag Name"));
}
}
private ObservableCollection<ViewTag> _childTags;
public ObservableCollection<ViewTag> ChildTags
{
get { return _childTags; }
set
{
_childTags = value;
OnPropertyChanged(new PropertyChangedEventArgs("Child Tags"));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
#endregion
public ViewTag(string tagName, ObservableCollection<ViewTag> childTags)
{
_tagName = tagName;
_childTags = childTags;
}
}
public class ViewNavigationTree
{
public string Image { get; set; }
public string Header { get; set; }
public ObservableCollection<ViewTag> Children { get; set; }
}
And my test binding is:
var xy = new List<ViewNavigationTree>();
List<ViewTag> tempTags = new List<ViewTag>();
ViewTag t1, t2, t3, t4, t5, t6;
t1 = new ViewTag("Computers", null);
t2 = new ViewTag("Chemistry", null);
t3 = new ViewTag("Physics", null);
var t123 = new ObservableCollection<ViewTag>();
t123.Add(t1);
t123.Add(t2);
t123.Add(t3);
t4 = new ViewTag("Science", t123);
var t1234 = new ObservableCollection<ViewTag>();
t1234.Add(t4);
t5 = new ViewTag("All Items", t1234);
t6 = new ViewTag("Untagged", null);
var tall = new ObservableCollection<ViewTag>();
tall.Add(t5);
tall.Add(t6);
xy.Add(new ViewNavigationTree() { Header = "Tags", Image = "img/tags2.ico", Children = tall });
var rootFolders = eDataAccessLayer.RepositoryFacrory.Instance.MonitoredDirectoriesRepository.Directories.ToList();
var viewFolders = new ObservableCollection<ViewTag>();
foreach (var vf in rootFolders)
{
viewFolders.Add(new ViewTag(vf.FullPath, null));
}
xy.Add(new ViewNavigationTree() { Header = "Folders", Image = "img/folder_16x16.png", Children = viewFolders });
xy.Add(new ViewNavigationTree() { Header = "Authors", Image = "img/user_16x16.png", Children = null });
xy.Add(new ViewNavigationTree() { Header = "Publishers", Image = "img/powerplant_32.png", Children = null });
TreeView2.ItemsSource = xy;
Problem is, the tree only shows:
+ Tags
All Items
Untagged
+ Folders
dir 1
dir 2
...
Authors
Publishers
The items I added under "All Items" aren't displayed.
Being a WPF nub, i can't put my finger on the problem. Any help will be greatly appriciated.
The only thing that jumps out here is that you're referencing the Children property in your ChildTemplate instead of ChildTags as defined in ViewTag.
For TreeView binding, you need to use a HierarchicalDataTemplate. This allows you to specify both the data for the node, and also the children for the node (by binding to ItemsSource).

Categories