Click here to Skip to main content
15,892,059 members
Articles / Programming Languages / C#

File / Folder Selection Control

Rate me:
Please Sign up or sign in to vote.
2.80/5 (9 votes)
24 Jul 2007CPOL4 min read 29.4K   997   11  
A file / folder selection control that hides the selection until needed.

Introduction

In one of my current projects, I found the need for a file / folder selection control. Originally, I decided to use the OpenFileDialog control. However, I could not find an OpenFolderDialog control to go along with it (in .NET 1.0). I then decided to use a combination of the VB style DriveListBox, DirListBox, and FileListBox controls. However, these three controls took up a lot of space on my form. I really needed to be able to hide the selection process (kind of like the DatePicker control). I could have done this with a Panel, but I wanted to make a control just in case I would need it again.

Maximized for file / folder selection

Screenshot - Maximized.jpg

Minimized when not in use

Screenshot - Minimized.jpg

Design Issues

There were a couple of key issues that arose during the development process. I'll just give a brief explanation of how I conquered these issues.

File / Folder Selection

My original plan was to use the TreeView control to load the files and folders from the computer. Before getting too deep into the code, I decided to look and see if someone had created a control that would do this for me. I couldn't find one, so I decided to use the old VB controls. I'm not particularly satisfied with this solution, but it works. The following events were used to connect the driveListBox, dirListBox, and fileListBox together:

C#
private void driveListBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
    //Set the local directory tag to the selected Drive
    this._Directory = driveListBox1.Drive.Substring(0, 2);
    //Set the directory list box to the selected drive
    dirListBox1.Path = _Directory + @"\";
    //Set the full path text box to the new directory
    txtFullPath.Text = dirListBox1.Path;
    //Set the local filename to an empty string
    _FileName = "";
}

private void dirListBox1_Change(object sender, System.EventArgs e)
{
    //Update the directory of the control
    this._Directory = dirListBox1.Path;
    //Set the fileListBox's path to the new directory
    fileListBox1.Path = _Directory;
    //Set the textbox to the new directory
    txtFullPath.Text = _Directory;
    //Fire the DirChanged event
    OnDirChanged();
    //Set the local filename to an empty string
    _FileName = "";
}

private void fileListBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
    //Reset the control to minimized view
    cmdExpand.ImageIndex = 0;
    cmdExpand.Tag = "Minimized";
    this.Height = 40;
    //Update the filename of the control
    this._FileName = fileListBox1.FileName;
    //If the directory already ends with a slash, 
    //there is no need to add one
    if (_Directory.EndsWith(@"\"))
    txtFullPath.Text = _Directory + _FileName;
    else
    txtFullPath.Text = _Directory + "\\" + _FileName;
    //Fire the FileChanged event
    OnFileChanged();
}

User Defined Properties

When I started this project, I had no idea how to define properties for a UserControl. It wasn't hard to find on the internet though. I decided to override the BackColor, ForeColor, Enabled, and Font properties. Also, I provided the Directory, FileName, FullPath, Mode, and Pattern properties. Below is a table containing the descriptions of all of the properties:

PropertyDescription
BackColorGets / Sets the back color of the driveListBox, dirListBox, fileListBox, and the full path of the TextBox controls contained inside the UserControl.
ForeColorGets / Sets the forecolor of the driveListBox, dirListBox, fileListBox, and the full path of the TextBox controls contained inside the UserControl.
FontGets / Sets the font of the driveListBox, dirListBox, fileListBox, and the full path of the TextBox controls contained inside the UserControl.
EnabledEnables / disables the control.
DirectoryGets the currently selected directory.
FileNameGets the currently selected file's name.
FullPathGets the full path of the selected file or folder (directory + \ + file name).
Mode

Gets / Sets the selection mode of the control:

  • DirMode = Only a folder can be selected.
  • FileMode = Only a file can be selected.
  • Both = Either a folder or a file can be selected.
PatternGets / Sets the filter of the FileListBox.

The main problem that I encountered with the properties was that I couldn't get them to serialize to the background code. For example, when I would place the control on a form and change the colors, it would be OK at Design time. However, when I run the project, the colors switch back to default. To fix this problem, I had to add a DesignerSerializationVisibility attribute.

C#
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always), 
   DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override System.Drawing.Color BackColor
{
    get
    {
        //return the current BackColor
        return _BackColor;
    }
    set
    {
        //Set the BackColor of all of the embedded controls
        _BackColor = value;
        base.BackColor = value;
        dirListBox1.BackColor = value;
        driveListBox1.BackColor = value;
        fileListBox1.BackColor = value;
        txtFullPath.BackColor = value;
    }
}

User Defined Events

I wanted to add two events to my control: DirChanged and FileChanged. The DirChanged event would fire when the dirListBox1_Change() event is called. The FileChanged event would fire when the fileListBox1_SelectedIndexChanged() event is called. To define events, I had to do the following:

  1. Declare the delegate event handlers:
  2. C#
    public delegate void FileChangedEventHandler(object sender, EventArgs e);
    public delegate void DirChangedEventHandler(object sender, EventArgs e);
  3. Define the new events in the control's member declaration:
  4. C#
    public event FileChangedEventHandler FileChanged;
    public event DirChangedEventHandler DirChanged;
  5. Declare the functions that call the events:
  6. C#
     protected virtual void OnFileChanged()
    {
        //Only call the event if it has been declared
        if (FileChanged != null)
        FileChanged(this, new EventArgs());
    }
    protected virtual void OnDirChanged()
    {
        //Only call the event if it has been declared
        if (DirChanged != null)
        DirChanged(this, new EventArgs());
    }
  7. Add a call to these two functions inside the fileListBox1_SelectedIndexChanged() and dirListBox1_Change() events.

Using the Control

In the demo project, I first added a reference to the control and added the control to my ToolBox. Then, I placed the control on the form and changed the BackColor to Yellow, ForeColor to Black, and Font to Arial, Bold, 10pt. Below is the code that was generated inside the InitializeComponent() function:

C#
private void InitializeComponent()
{
    ...
    this.fileSelect1.BackColor = System.Drawing.Color.Yellow;
    this.fileSelect1.Font = new System.Drawing.Font("Arial", 9.75F, 
                            System.Drawing.FontStyle.Bold, 
                            System.Drawing.GraphicsUnit.Point, 
                            ((System.Byte)(0)));
    this.fileSelect1.ForeColor = System.Drawing.Color.Black;
    ...
}

Then, I added a couple of Labels to the form and connected their text to the Directory, FileName, and FullPath properties of the control. The DirChanged and FileChanged events were used to accomplish this.

C#
private void fileSelect1_DirChanged(object sender, System.EventArgs e)
{
    label2.Text = fileSelect1.Directory;
    label1.Text = fileSelect1.FullPath;
}

private void fileSelect1_FileChanged(object sender, System.EventArgs e)
{
    label3.Text = fileSelect1.FileName;
    label1.Text = fileSelect1.FullPath;
}

Future

I would like to change the file selection process to a TreeView and ListView control. So, I will continue doing research on that. Also, you can manually edit the TextBox that contains the full path. However, this does not automatically browse the driveListBox, dirListBox, and fileListBox. I attempted to allow the control to be re-sized, but decided to leave that for another day. Other than that, I don't really see a future for this control. Like I said, I just needed something simple to do the job. Hopefully, this article has been helpful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer
United States United States
I am a senior at the University of Alabama. I will get my bachelor's in December 2007 in Electrical and Computer Engineering. I have experience in the automated controls industry with PLC programming and HMI development. Also, I have written many programs and utilities in VB, C, C++, and C#.

Comments and Discussions

 
-- There are no messages in this forum --