c# wpf treeview code-behind

c# - poblar treeview de la lista de rutas de archivos en wpf



code-behind (2)

Hay varios ejemplos de cómo llenar una vista en árbol de una colección de rutas de archivos como this u este otro ejemplo. Parece que no puedo encontrar ese ejemplo para WPF. Sé que puedo integrar formularios de Windows y usar un control diferente para hacerlo funcionar, pero sería bueno si pudiera hacer lo mismo con un control treeview wpf. La vista en árbol que quiero construir consta de aproximadamente 50,000 archivos, por lo tanto, creo que será mejor si se vincula a algo. Pero antes de enlazarlo, creo que será útil construir uno basado en una lista de cadenas (las cadenas contienen las rutas de los archivos).


Estaba intrigado por la pregunta y arrojé esto juntos. Como primer paso, creo que estoy bastante cerca de lo que estás buscando. Hablar de 50,000 artículos me hace pensar que la carga lenta puede ser apropiada. De todos modos, aquí está la versión simple basada en un article de Josh Smith. Puse todo el código aquí, pero la magia realmente tiene lugar con las plantillas de datos.

Dadas algunas clases para representar los objetos con los que estamos trabajando ...

using System.Collections.Generic; namespace WpfTreeViewBinding.Model { public class Item { public string Name { get; set; } public string Path { get; set; } } }

y...

namespace WpfTreeViewBinding.Model { public class FileItem : Item { } }

y...

namespace WpfTreeViewBinding.Model { public class DirectoryItem : Item { public List<Item> Items { get; set; } public DirectoryItem() { Items = new List<Item>(); } } }

Creé un método recursivo para cargar algunos directorios / archivos ...

using System.Collections.Generic; using System.IO; using WpfTreeViewBinding.Model; namespace WpfTreeViewBinding { public class ItemProvider { public List<Item> GetItems(string path) { var items = new List<Item>(); var dirInfo = new DirectoryInfo(path); foreach(var directory in dirInfo.GetDirectories()) { var item = new DirectoryItem { Name = directory.Name, Path = directory.FullName, Items = GetItems(directory.FullName) }; items.Add(item); } foreach(var file in dirInfo.GetFiles()) { var item = new FileItem { Name = file.Name, Path = file.FullName }; items.Add(item); } return items; } } }

A partir de ahí, solo se trata de obtener la información ...

using System.Windows; namespace WpfTreeViewBinding { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var itemProvider = new ItemProvider(); var items = itemProvider.GetItems("C://Temp"); DataContext = items; } } }

Y mostrándolo ...

<Window x:Class="WpfTreeViewBinding.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Model="clr-namespace:WpfTreeViewBinding.Model" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <HierarchicalDataTemplate DataType="{x:Type Model:DirectoryItem}" ItemsSource="{Binding Items}"> <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" /> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type Model:FileItem}"> <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" /> </DataTemplate> </Window.Resources> <Grid Margin="8"> <TreeView ItemsSource="{Binding}" /> </Grid> </Window>

Toda la magia realmente sucede con las plantillas de datos. Supongo que la clave de todo es utilizar HierarchicalDataTemplate para cualquier elemento con jerarquía (es decir, directorios).

NOTA 1: No he probado extensivamente esto. No ha sido perfilado para el rendimiento. Me gustaría recibir cualquier comentario, ya que este es un problema que traté de resolver hace mucho tiempo y desistí. ¡Gracias!

NOTA 2: Tendrá que establecer la ruta codificada a algo que tenga sentido en su sistema.

Aquí hay una captura de pantalla que muestra los directorios y archivos en diferentes niveles ...


Pequeña extensión para la solución anterior: agregué el código xaml para admitir los íconos y soporte para cambiar entre los íconos de la carpeta abierta y cerrada:

<HierarchicalDataTemplate DataType="{x:Type viewModels:SourceControlDirecoryViewModel}" ItemsSource="{Binding Items}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="5" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Image Width="16" Height="16" Source="{StaticResource ImageSourceFolderClosed16x16}" x:Name="img" /> <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" Grid.Column="2" /> </Grid> <DataTemplate.Triggers> <DataTrigger Binding="{Binding IsExpanded, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TreeViewItem}}}" Value="True"> <Setter Property="Source" TargetName="img" Value="{StaticResource ImageSourceFolderOpened16x16}" /> </DataTrigger> </DataTemplate.Triggers> </HierarchicalDataTemplate>