Отображение файлов директории WPF C#
Всем привет у меня написана та часть, которая просматривает директории и получает файлы которые там находятся, снизу пример класса который содержит это всё. У меня вопрос как мне отображать эти данные в TreeView или во что то похожее, причет поиск файлов происходит в отдельном потоке ,как понимаете элементы в нем обновляются. Я хочу что бы моё дерево динамически отрисовывалось.
class FileSystemNode : IEnumerable<FileSystemNode>
{
private List<FileSystemNode> nodes;
public void Add(FileSystemNode node) => nodes.Add(node);
public IEnumerable<FileSystemNode> FileSystemNodes
{
get
{
foreach (var node in nodes)
yield return node;
}
}
public string Name { get => Path.GetFileName(FullPath); }
public bool IsFile { get; set; }
public string FullPath { get; set; }
public FileSystemNode() => nodes = new List<FileSystemNode>();
public bool HasFile
{
get => IsFile || nodes.Any(n => n.HasFile);
}
public IEnumerator<FileSystemNode> GetEnumerator()
=> FileSystemNodes.Where(n => n.HasFile).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public override string ToString()
=> string.IsNullOrEmpty(Name) ? FullPath : Name;
}
Ответы (1 шт):
Вам не нужно саму ноду делать IEnumerable, нода - это ячейка, элемент, она не коллекция, а коллекция - это дочерние ноды. Кстати при формировании логики дерева многие допускают эту ошибку, так что можно ее считать типовой и очень частой.
Берете INotifyPropertyChanged
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Берете ноду
public class TreeNode : NotifyPropertyChanged
{
private string _nodeName;
private ObservableCollection<TreeNode> _items;
public string NodeName
{
get => _nodeName;
set
{
_nodeName = value;
OnPropertyChanged();
}
}
public ObservableCollection<TreeNode> Items
{
get => _items;
set
{
_items = value;
OnPropertyChanged();
}
}
}
Добавляете в View Model свойство
private ObservableCollection<TreeNode> _treeNodes;
public ObservableCollection<TreeNode> TreeNodes
{
get => _treeNodes;
set
{
_treeNodes = value;
OnPropertyChanged();
}
}
И вяжете в TreeView
<TreeView ItemsSource="{Binding TreeNodes}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBlock Text="{Binding NodeName}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Всё, теперь добавляете в эту стуктуру полей и свойств по вкусу, дополняете разметку и готово - TreeView будет отслеживать все изменения в дереве автоматически.
Кстати, тип ноды можете обеспечить с помощью наследования
public class FileNode : TreeNode
{
// ...
}
public class DirectoryNode : TreeNode
{
// ...
}
Тогда для каждого типа ноды можно свою разметку будет замутить
<TreeView ItemsSource="{Binding TreeNodes}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:FileNode}" ItemsSource="{Binding Items}">
<TextBlock Text="{Binding NodeName}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:DirectoryNode}" ItemsSource="{Binding Items}">
<TextBlock Text="{Binding NodeName,StringFormat=[{0}]}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Ну и как вы уже поняли, свойство IsFile больше не нужно. Просто добавляйте нужный тип ноды, а интерфейс подберет под него разметку.
node.Items.Add(new FileNode { NodeName = "file.txt" });