Есть ли диалоговое окно для выбора сочетания нескольких файлов и папок одновременно? - PullRequest
0 голосов
/ 30 августа 2018

Я понимаю, что уже есть ряд вопросов, очень похожих на это:

мульти-выбор папок и файлов

Диалог C # для выбора нескольких файлов И папок

C # - Как настроить OpenFileDialog для выбора нескольких папок и файлов?

Обязательный диалог для выбора нескольких файлов и папок .NET

Выберите файл или папку из того же диалогового окна в .NET

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

Это выглядит именно то, что я ищу ... За исключением того, что это C ++, и я понятия не имею, как я мог бы использовать его в .NET (это возможно):

https://www.codeproject.com/Articles/28015/SelectDialog-A-Multiple-File-and-Folder-Select-Dia

Я понимаю, что очень маловероятно, чтобы в .NET был встроен диалог, который я пропустил. Однако, поскольку я думаю, что это было бы довольно распространенным требованием, я бы подумал, что что-то уже будет сделано, а не я сам по себе. Это заняло бы относительно много времени и, вероятно, оказалось бы гораздо более базовым, чем встроенный OpenFileDialog (все это с базовой функциональностью, которая нам нужна).

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

Какой самый быстрый и простой способ для меня реализовать такой диалог в Winforms?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Несмотря на то, что я не использовал ни один из предоставленного кода, я собираюсь принять ответ @ mdsimps99, так как вопрос был: «Какой самый быстрый и простой способ для меня реализовать такой диалог в Winforms?», и он ответил, что я должен катиться самостоятельно (к сожалению).

Однако я подумал, что выложу свое не идеальное решение для полноты.

У меня не было времени сделать то, что я хотел бы, и создать собственное решение, полностью эмулирующее OpenFileDialog. Поэтому вместо этого я создал «SelectPathsDialog», который находится между моей основной программой и OpenFileDialog (и FolderBrowserDialog).

Это очень просто:

enter image description here

Кнопка «Добавить файлы» открывает OpenFileDialog и добавляет выбранные файлы в список. Кнопка «Добавить папки» открывает FolderBrowserDialog и добавляет выбранную папку в список.

Он отражает все общедоступные свойства, которые я уже использовал из OpenFileDialog. Это означает, что в моей основной программе я смог легко заменить все вызовы «OpenFileDialog» на «SelectPathsDialog», и он будет работать правильно.

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

Поскольку я планирую улучшить его в будущем, я использовал сторонний элемент управления ObjectListView, поскольку он гораздо более универсален, чем стандартный ListView.

Как я говорю. Это не идеально. Но он пока работает, и я всегда могу вернуться к нему позже, когда давление не так велико.

0 голосов
/ 31 августа 2018

Ниже приведен скриншот пользовательского интерфейса и некоторых фрагментов кода (в основном обработчиков событий), связанных с реализацией диалогового окна выбора файла И папки, о котором я упоминал в своем комментарии.

Хотя весь код, относящийся к навигации по каталогам и фактическому извлечению путей к файлам, находится на другом уровне кода (оболочка вокруг API управления версиями), это должно дать вам представление о том, как можно реализовать диалог выбора файла И папки с включенным выбором нескольких элементов с точки зрения управления. Простая кнопка, чтобы сжать текущий выбор, может вызвать GetSourceSelectedFilePaths (или как вы можете назвать его), а затем сжать все эти пути вместе.

Я подозреваю, что класс System.IO.Directory содержит почти все методы, которые вам понадобятся для обработки части навигации по файлам / каталогам.

Это, конечно, не очень эстетично, и я знаю, что вы не заинтересованы в том, чтобы реализовать это самостоятельно, но это, безусловно, возможно (и относительно легко, если вы можете жить с чем-то, что выглядит так). Если бы у меня было больше времени, я бы заменил все эти вызовы обертки API на вызовы методов System.IO.Directory, чтобы сделать это немного яснее.

Basic File / Folder Browser Dialog

// Method to display contents at current level (folders and files) to controls
private void AddToDisplayChildFolderContents(APIObject curVaultWrapper, ListBox childFolder_LB, ListBox childFiles_LB)
{
    var curDocNames = curVaultWrapper.GetCurFolderDocNames(); // API wrapper call to get all documents in current folder

    if (curDocNames.Count > 0)
    {
        childFiles_LB.Items.Clear();
        childFiles_LB.Items.AddRange(curDocNames.ToArray());
    }

    var childFolderList = = curVaultWrapper.GetCurChildFolderNames(); // API wrapper call to get all folders in current folder
    if (childFolderList.Count > 0)
    {
        childFolder_LB.Items.Clear();
        childFolder_LB.Items.AddRange(returnStatus.items.ToArray());
    }
}

// Method to navigate up one directory
private void srcGoUp_B_Click(object sender, EventArgs e)
{
    if (VaultCopyConfig.SrcVault.DrillOutOfVaultFolder()) // API wrapper method returns true if current folder is root, points version controlled file system API wrapper one directory up
    {
        this.srcGoUp_B.Enabled = false;
    }

    DisplayVaultFolderContents(VaultCopyConfig.SrcVault, srcCurrentFolder_TB, srcDrill_IntoSubFolder_CB,
         srcChildFolders_LB, srcFiles_LB);
}

// Method to navigate one directory lower
private void srcDrill_IntoSubFolder_CB_SelectedIndexChanged(object sender, EventArgs e)
{
    var selectedSubFolderName = srcDrill_IntoSubFolder_CB.Text;

    VaultCopyConfig.SrcVault.DrillIntoVaultFolder(selectedSubFolderName, false); // call to our API wrapper

    DisplayVaultFolderContents(vaultCopyConfig.srcVault, srcCurrentFolder_TB, srcDrill_IntoSubFolder_CB,
               srcChildFolders_LB, srcFiles_LB);

    this.srcGoUp_B.Enabled = true;
}

// Method that is called to aggregate all user selections (then sends to our API wrapper to actually validate / process / consolidate paths
private List<string> GetSourceSelectedFilePaths(bool dlgFlag)
{
    var filePaths = new List<string>();

    var validFolderNames = new List<string>();
    var validFileNames = new List<string>();

    if (srcChildFolders_LB.Items.Count > 0)
    {
        string selectedItem;
        foreach (int i = 0; i < srcChildFolders_LB.Items.Count; i++)
        {
            if (srcChildFolders_LB.GetSelected(i))
            {
                selectedItem = srcChildFolders_LB.Items[i].ToString();
                validFolderNames.Add(selectedItem);
            }
        }
    }
    if (srcFiles_LB.Items.Count > 0)
    {
        var selectedItem;
        for (int i = 0; i < srcFiles_LB.Items.Count; i++)
        {
            if (srcFiles_LB.GetSelected(i))
            {
                selectedItem = srcFiles_LB.Items[i].ToString();
                validFileNames.Add(selectedItem);
            }
        }
    }

    filePaths = VaultCopyConfig.SrcVault.GetSelectedFilePaths(validFolderNames, validFileNames, dlgFlag); // call to API wrapper to validate / consolidate list of all filepaths in user selection

    return filePaths;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...