Заполните древовидную структуру WPF в отдельной ветке
Буду признателен за советы по моей проблеме ниже: мне нужно, чтобы мое приложение WPF для настольного компьютера запускало два отдельных потока: Первый поток: сканирование каталога на наличие файлов. Второй поток: получает объект FileInfo из первого потока и помещает его как новый TreeViewItem в элемент управления TreeView. Я пытаюсь решить эту проблему с помощью Monitor
статические методы.
public partial class MainWindow : Window
{
private Thread scanThread, treeThread;
public FileInfo scannedFile;
public object _lock = new object();
public MainWindow()
{
InitializeComponent();
scanThread = new Thread(new ParameterizedThreadStart(Scan));
treeThread = new Thread(new ThreadStart(PopulateTree));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
DirectoryInfo directory = new DirectoryInfo(FolderPath.Text); //I get FolderPath from FolderBrowserDialog
scanThread.Start(directory);
treeThread.Start();
}
public void Scan(object dir)
{
DirectoryInfo _directory = (DirectoryInfo)dir;
foreach (var file in _directory.GetFiles())
{
lock (_lock)
{
scannedFile = file;
Monitor.Pulse(_lock);
Monitor.Wait(_lock);
}
}
}
public void PopulateTree()
{
this.Dispatcher.Invoke(() =>
{
if (scannedFile== null)
return;
lock (_lock)
{
var dirNode = new TreeViewItem();
dirNode.Items.Add(scannedFile.Name);
dirNode.Header = scannedFile.Name;
MyTreeView.Items.Add(dirNode);
Monitor.Pulse(_lock);
Monitor.Wait(_lock);
}
});
}
В конце концов я получаю случайные странные результаты - либо в древовидную структуру популяции вообще нет, либо в древовидную структуру добавляется только последний файл из папки Может быть, это Monitor
Логика Я не могу заставить работать должным образом, или я не должен использовать общедоступную переменную scannedFile и передавать каждый var file in _directory.GetFiles()
по-другому во второй теме? Заранее спасибо! Обновление Я ограничен некоторыми базовыми методами, такими как Monitor/waithandle, поэтому решение должно быть принято в рамках этих методов.
1 ответ
Я бы порекомендовал принять шаблон MVVM, если вы используете WPF. Вам следует избегать использования кода в окне и позволить WPF позаботиться о логике мониторинга / потоков. Чтобы сделать это, вы должны создать модель объектов вашего файла / каталога (возможно, с родительским классом FileSystemObject
или что-то типа того). Тогда у вас в вашей ViewModel будет какая-то ObservableCollection<FileSystemObject>
доступны для рендеринга в вашем представлении, которое будет содержать ваши TreeView
, Пример кода уведомления WPF TreeView ObservableCollection имеет хороший пример выполнения чего-то похожего на то, что вы могли бы использовать в качестве отправной точки.