Pergunta

Lembro -me do VB6, havia um controle semelhante a um Dropbox/ComboBox que você pode selecionar o nome da unidade. Ele levanta um evento que você pode definir outro controle que enumeram arquivos no ListBox. (no drive.event você faz arquivos.path = drive.path para obter esse efeito).

Existe algo assim em C#? Um controle que retira uma lista de unidades disponíveis e levanta um evento quando é alterado?

Foi útil?

Solução

There's no built-in control to do that, but it's very easy to accomplish with a standard ComboBox. Drop one on your form, change its DropDownStyle to DropDownList to prevent editing, and in the Load event for the form, add this line:

comboBox1.DataSource = Environment.GetLogicalDrives();

Now you can handle the SelectedValueChanged event to take action when someone changes the selected drive.

After answering this question, I've found another (better?) way to do this. You can use the DriveInfo.GetDrives() method to enumerate the drives and bind the result to the ComboBox. That way you can limit which drives apppear. So you could start with this:

comboBox1.DataSource = System.IO.DriveInfo.GetDrives();
comboBox1.DisplayMember = "Name";

Now comboBox1.SelectedValue will be of type DriveInfo, so you'll get lots more info about the selected game. And if you only want to show network drives, you can do this now:

comboBox1.DataSource = System.IO.DriveInfo.GetDrives()
    .Where(d => d.DriveType == System.IO.DriveType.Network);
comboBox1.DisplayMember = "Name";

I think the DriveInfo method is a lot more flexible.

Outras dicas

While Matt Hamiltons answer was very correct, I'm wondering if the question itself is. Because, why would you want such a control? It feels very Windows 95 to be honest. Please have a look at the Windows User Experience Interaction Guidelines: http://msdn.microsoft.com/en-us/library/aa511258.aspx

Especially the section about common dialogs: http://msdn.microsoft.com/en-us/library/aa511274.aspx

I would approach this with:

foreach (var Drives in Environment.GetLogicalDrives())
{
    DriveInfo DriveInf = new DriveInfo(Drives);
    if (DriveInf.IsReady == true)
    {
        comboBox1.Items.Add(DriveInf.Name);
    }
}

With the help of Drive.IsReady u can avoid having DeviceNotReady or DeviceUnavailable issues.

Bonus: Also here is a simple "ChooseFile" example which includes a ComboBox for drives, a TreeView for folders and the last a ListBox for files.

namespace ChosenFile
{
    public partial class Form1 : Form
    {
        // Form1 FormLoad
        //
        public Form1()
        {
            InitializeComponent();
            foreach (var Drives in Environment.GetLogicalDrives())
            {
                DriveInfo DriveInf = new DriveInfo(Drives);
                if (DriveInf.IsReady == true)
                {
                    comboBox1.Items.Add(DriveInf.Name);
                }
            }
        }

        // ComboBox1 (Drives)
        //
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedItem != null)
            {
                ListDirectory(treeView1, comboBox1.SelectedItem.ToString());
            }
        }

        // ListDirectory Function (Recursive Approach):
        // 
        private void ListDirectory(TreeView treeView, string path)
        {
            treeView.Nodes.Clear();
            var rootDirectoryInfo = new DirectoryInfo(path);
            treeView.Nodes.Add(CreateDirectoryNode(rootDirectoryInfo));
        }
        // Create Directory Node
        // 
        private static TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
        {
            var directoryNode = new TreeNode(directoryInfo.Name);
            try
            {
                foreach (var directory in directoryInfo.GetDirectories())
                    directoryNode.Nodes.Add(CreateDirectoryNode(directory));
            }
            catch (Exception ex)
            {
                UnauthorizedAccessException Uaex = new UnauthorizedAccessException();
                if (ex == Uaex)
                {
                    MessageBox.Show(Uaex.Message);
                }
            }
            return directoryNode;
        }

        // TreeView
        // 
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            listBox1.Items.Clear();
            listBox1.Refresh();
            PopulateListBox(listBox1, treeView1.SelectedNode.FullPath.ToString(), "*.pdf");
        }
        // PopulateListBox Function
        // 
        private void PopulateListBox(ListBox lsb, string Folder, string FileType)
        {
            try
            {
                DirectoryInfo dinfo = new DirectoryInfo(Folder);
                FileInfo[] Files = dinfo.GetFiles(FileType);
                foreach (FileInfo file in Files)
                {
                    lsb.Items.Add(file.Name);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occurred while attempting to load the file. The error is:"
                                + System.Environment.NewLine + ex.ToString() + System.Environment.NewLine);
            }
        }

        // ListBox1
        //
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox1.SelectedItem != null)
            {
                //do smt here!
                MessageBox.Show(listBox1.SelectedItem.ToString());
            }
        }
    }
}

Just like the old times in VB6.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top