{ // string path; // string path1; public MainWindow() { InitializeComponent(); foreach (DriveInfo drive in DriveInfo.GetDrives()) { TreeViewItem item = new TreeViewItem(); item.Tag = drive; item.Header = drive.ToString(); item.Items.Add("*"); tree.Items.Add(item); } } private void treeView_Expanded(object sender, RoutedEventArgs e) { try { TreeViewItem item = (TreeViewItem)e.OriginalSource; item.Items.Clear(); tree.SelectedItemChanged += Tree_SelectedItemChanged; TreeViewItem sItem; DirectoryInfo[] dirs; FileInfo[] files = null; if (item.Tag is DriveInfo) dirs = new DirectoryInfo(item.Header.ToString()).GetDirectories(); else { dirs = ((DirectoryInfo)item.Tag).GetDirectories(); files = ((DirectoryInfo)item.Tag).GetFiles(); } foreach (DirectoryInfo dir in dirs) { sItem = new TreeViewItem(); sItem.Header = dir.ToString(); sItem.Tag = dir; sItem.Items.Add("*"); item.Items.Add(sItem); } if (files != null) foreach (FileInfo file in files) item.Items.Add(file); } catch (Exception) { } } private void Tree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) { } 

    1 answer 1

    If you reject the prompting remarks about OOP and MVVM and try to solve the problem using the approach given by the author, you get something like that.

    XAML:

     <TreeView x:Name="TreeView" TreeViewItem.Expanded="OnTreeViewItemExpanded" SelectedItemChanged="OnTreeViewSelectedItemChanged" VirtualizingPanel.IsVirtualizing="True"/> 

    Everything here is obvious except for the inclusion of virtualization - for folders with a large number of files, this code notably slows down without virtualization.

    Codebehind:

      public MainWindow() { InitializeComponent(); foreach (var drive in DriveInfo.GetDrives()) { var dir = drive.RootDirectory; TreeView.Items.Add(GetDirNode(dir)); } } private void OnTreeViewItemExpanded(object sender, RoutedEventArgs e) { try { var item = (TreeViewItem)e.OriginalSource; item.Items.Clear(); var dirs = ((DirectoryInfo)item.Tag).GetDirectories(); var files = ((DirectoryInfo)item.Tag).GetFiles(); foreach (var dir in dirs) { item.Items.Add(GetDirNode(dir)); } foreach (var file in files) { item.Items.Add(GetFileNode(file)); } } catch (Exception) { } } private TreeViewItem GetNode(FileSystemInfo info) { var result = new TreeViewItem(); result.Header = info.ToString(); result.Tag = info; return result; } private TreeViewItem GetFileNode(FileInfo fileInfo) { return GetNode(fileInfo); } private TreeViewItem GetDirNode(DirectoryInfo directoryInfo) { var result = GetNode(directoryInfo); result.Items.Add("*"); return result; } private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) { MessageBox.Show(((e.NewValue as TreeViewItem).Tag as FileSystemInfo).FullName); } 

    The main change to the original code is the transition to storage in all nodes of the TreeViewItem tree, which has one or another FileSystemInfo (the ancestor of FileInfo and DirectoryInfo ) in the Tag property. This allows you to consistently get a directory for any node in the tree, regardless of whether the node is a disk, folder or file. The problem with displaying an unnecessary button-expander for files is solved by not adding children for the file node.

    If there are any questions, I will answer for sure.

    • It is not clear how we get the path (e.NewValue as TreeViewItem) .Tag as FileSystemInfo .FullName. Why several properties are used, instead of one fullname - test19
    • In general, regarding this line, it is not quite clear how to use the construction as - test19
    • one
      @SOFL does not use several properties at once. This entry is a cascade of type casts and a selection of their properties. Roughly speaking, it will unfold in [it] ( gist.github.com/dmdymov/4bfc5640f87e46489318468a1925f957 ). The as construct is a "soft" explicit type conversion operator that does not throw an exception if the casting is not possible, but simply returns null. An example with a description of the work here . - dm.dymov
    • one
      @SOFL this string can be written, including via explicit casts, as (((FileSystemInfo) ((TreeViewItem) e.NewValue) .Tag) .FullName , in this form it can be clearer. - dm.dymov