File / Folder Selection Control






2.80/5 (9 votes)
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.
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:
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:
Property | Description |
BackColor |
Gets / Sets the back color of the driveListBox , dirListBox , fileListBox , and the full path of the TextBox controls contained inside the UserControl. |
ForeColor |
Gets / Sets the forecolor of the driveListBox , dirListBox , fileListBox , and the full path of the TextBox controls contained inside the UserControl. |
Font |
Gets / Sets the font of the driveListBox , dirListBox , fileListBox , and the full path of the TextBox controls contained inside the UserControl. |
Enabled |
Enables / disables the control. |
Directory |
Gets the currently selected directory. |
FileName |
Gets the currently selected file's name. |
FullPath |
Gets the full path of the selected file or folder (directory + \ + file name). |
Mode |
Gets / Sets the selection mode of the control:
|
Pattern |
Gets / 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.
[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:
- Declare the delegate event handlers:
- Define the new events in the control's member declaration:
- Declare the functions that call the events:
- Add a call to these two functions inside the
fileListBox1_SelectedIndexChanged()
anddirListBox1_Change()
events.
public delegate void FileChangedEventHandler(object sender, EventArgs e);
public delegate void DirChangedEventHandler(object sender, EventArgs e);
public event FileChangedEventHandler FileChanged;
public event DirChangedEventHandler DirChanged;
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());
}
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:
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 Label
s 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.
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.