Как показать все данные/папки, связанные с диском, в дереве?

 cmbDrives.DataSource = Environment.GetLogicalDrives();

У меня есть этот код, чтобы показать все диски в поле со списком, и я хочу показать связанные данные All Drive в treeview на событии comboboxselectionchanged.

Как я могу это сделать?


person Elixir    schedule 15.07.2015    source источник
comment
Как показать данные дисков при выборе измененных   -  person Elixir    schedule 15.07.2015
comment
Не полезно для того, что я нахожу   -  person Elixir    schedule 15.07.2015
comment
Я хочу, если я выберу c Drive, он отобразит файл программы и т. Д. C в дереве.   -  person Elixir    schedule 15.07.2015
comment
Но это не выбор в выпадающем списке изменился. Я уже видел это.   -  person Elixir    schedule 15.07.2015


Ответы (1)


Следующий код достигает того, чего вы хотите, используя фоновую работу, чтобы убедиться, что пользовательский интерфейс остается отзывчивым, пока выполняется прогресс во время обхода папки.

Сначала добавьте ComboBox, Treeview и BackgroundWorker в область разработки. Не забудьте добавить события, используемые в следующем коде, из окна свойств для каждого элемента управления с помощью представления событий. Обязательно установите для свойства WorkerReportsProgress значение true для BackgroundWorker.

Сначала событие ComboBox SelectionIndexChanged:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    this.comboBox1.Enabled = false;
    this.backgroundWorker1.RunWorkerAsync(comboBox1.SelectedItem.ToString());
}

Мы отключаем наше поле со списком, чтобы предотвратить выбор нового значения, пока мы обрабатываем обход диска. Затем мы запускаем наш BackgroundWorker, передавая ему SelectedItem, который, как мы предполагаем, является действительным диском.

Фоновый рабочий

Событие DoWork принимает eventargs, у которого есть свойство Argument, содержащее значение, которое мы предоставили при вызове RunWorkerAsync. Поскольку сейчас мы находимся в потоке, отличном от пользовательского интерфейса, нам нужны некоторые хитрости для обновления пользовательского интерфейса. Фоновый рабочий может сделать это с помощью своего метода ReportProgress. Он принимает целое число, обычно используемое для определения того, как далеко мы находимся, и необязательное пользовательское состояние. Мы используем эти два, чтобы указать, в каком состоянии мы находимся, и предоставить TreeNode, который необходимо добавить или обновить в нашем TreeView. Затем он вызывает GetDirectoryNodes для обхода каталога.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    TreeNode node = new TreeNode(e.Argument.ToString());
    backgroundWorker1.ReportProgress(0, node);
    GetDirectoryNodes(e.Argument.ToString(), node);
}

ProgressChanged вызывается каждый раз, когда у нас есть TreeNode (или Tuple of TreeNodes), поэтому мы можем добавлять узлы в TreeView или один из его узлов, пока мы находимся в потоке пользовательского интерфейса. ProgressPercentage используется не для того, чтобы показать, как далеко мы продвинулись, а для того, чтобы отличить начальное состояние от состояния обхода.

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    switch (e.ProgressPercentage)
    {
        case 0:
            // we have s TreeNode, this is our root.
            treeView1.Nodes.Add((TreeNode) e.UserState);
            break;
        case 1:
            // we get a tuple, the parent and it's intended child.
            var tup = (Tuple<TreeNode,TreeNode>) e.UserState;
            tup.Item1.Nodes.Add(tup.Item2);
            break;
        default:
            break;
    }
}

Как только мы закончим (то есть пройдены все папки), мы снова включим поле со списком, чтобы мы могли выбрать новый диск.

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    this.comboBox1.Enabled = true;
}

Обход папки на диске

Для обхода дерева каталогов я использую рекурсивную функцию (во многом вдохновленную ответом Криса Балларда, которая вызывает метод BackgroundWorkers ReportProgress один раз у него есть TreeNode, который готов к добавлению в TreeView.Обратите внимание, как я использую Tuple в качестве объекта состояния, который содержит родительский и дочерний элементы для добавления, но это конкретное действие оставлено для события ProgressChanged в UI-Thread.

    private void GetDirectoryNodes(string path, TreeNode node)
    {
        try
        {
            var subDirs = Directory.GetDirectories(path);
            foreach (string p in subDirs)
            {
                var subnode = new TreeNode(p);
                backgroundWorker1.ReportProgress(
                    1, 
                    new Tuple<TreeNode, TreeNode>(
                        node, subnode
                        ));
                GetDirectoryNodes(p, subnode); // recursive!
            }
        }
        catch (Exception exp)
        {
            var subnode = new TreeNode(path+"\\error");
            subnode.ToolTipText = exp.Message;
            backgroundWorker1.ReportProgress(
                1, 
                new Tuple<TreeNode, TreeNode>(
                    node, subnode
                    ));
        }
    }
person rene    schedule 15.07.2015