Introduction
This article demonstrates the following features :
- Drag and Drop functionality
- Use of
ListBox
control and its events.
- Use of
RichEdit
control
- Use of
System.IO.Directory
class.
- Use of
HelpProvider
class for displaying a Help Text for controls on the form when user presses F1.
Using the code
As all of you have seen or used, the basic drag and drop functionality of dragging a text file from the Windows explorer and dropping it on an open instance of notepad, displays the contents of the file. I have implemented a similar functionality to demonstrate the drag and drop functionality using C#. Lets get started.
FileObject
As you can see in the picture above, we will be implementing our own explorer using a listbox and methods of System.IO.Directory
class. All of the above directories and files will be represented by one class called FileObject
. This class is shown below :
public class FileObject
{
private string fileName;
private string filePath;
private bool isFolder;
public FileObject(string name,bool folder)
{
string[] pieces = name.Split(new char[]{'\\'});
fileName = pieces[pieces.Length -1];
filePath = name;
isFolder = folder;
}
public string Name
{
get
{
return fileName;
}
}
public string NameWithPath
{
get
{
return filePath;
}
}
public bool IsFolder
{
get
{
return isFolder;
}
}
public override string ToString()
{
return fileName;
}
}
The above class provides simple properties for parsing the filename or foldername. The objects of this class will be added to the list as we navigate from folder to folder.
Explorer using ListBox
Since the ListBox will be acting as our explorer, we have to have the following functionality
- The user should be able to differentiate between a list item that is a folder from the item which is a file.
- The user should be able to navigate from folder to folder by double-Clicking on the folder.
- The user should be able to navigate back to the parent folders.
DrawItem Event
We will implement an eventhandler for the DrawItem
event to add the functionality to paint the folder items different from the file items. Here's the code...
list.MultiColumn = true;
list.DrawMode = DrawMode.OwnerDrawFixed;
list.MouseDown += new MouseEventHandler(this.OnMouseDown);
list.DoubleClick += new EventHandler(this.OnDblClick);
list.DrawItem += new DrawItemEventHandler(this.OnDrawItem);
The actual OnDrawItem
function does the following :
- If the item being drawn is a folder , paints it bold and red.
- If the item being drawn is a file,paints in normal black font.
- Adjust the column width to fit the longest folder/filename.
The code is shown below:
void OnDrawItem(object sender, DrawItemEventArgs drawArgs)
{
ListBox lb = (ListBox)sender;
int index = drawArgs.Index;
if(index >= 0)
{
obj = (FileObject)lb.Items[index];
Graphics g = drawArgs.Graphics;
Font f = new Font(drawArgs.Font,FontStyle.Bold);
if(obj.IsFolder)
g.DrawString(obj.Name,f,Brushes.Red,
drawArgs.Bounds.Left,drawArgs.Bounds.Top);
else
g.DrawString(obj.Name,drawArgs.Font,Brushes.Black,
drawArgs.Bounds.Left,drawArgs.Bounds.Top);
if(lb.ColumnWidth < obj.Name.Length * 10)
lb.ColumnWidth = obj.Name.Length * 10;
}
}
DoubleClick Event
We implement a DoubleClick
event handler for the listBox which will allow us to navigate into a folder when it is double-Clicked. The code is shown below :
void OnDblClick(object sender, EventArgs me)
{
ListBox lb = (ListBox)sender;
int index = lb.SelectedIndex;
if(index >= 0)
{
FileObject item = (FileObject)lb.Items[index];
if(item.IsFolder)
{
fillList(item.NameWithPath);
}
}
}
Back Button
This button when clicked will take us to the parent of the current folder.
void OnPrevClicked(object sender,EventArgs e)
{
string path = this.Text;
try{
DirectoryInfo info = Directory.GetParent(path);
if(info.FullName != "")
fillList(info.FullName);
}
catch
{
prev.Enabled = false;
}
}
Drag And Drop
Alright, we are almost done. Now this final pice will tie it all together. We will do the following:
- Start the drag and drop event when the user presses the mouse inside the listBox.
- Enable the rich edit control to accept the dragged data ONLY if its text or a file dragged from Explorer.
MouseDown Event
We write an eventHandler for MouseDown
event in ListBox
. When the mouse is pressed, we will :
- Make sure the item selected is a File.
- Send the file name along with its full path as arguments to
DoDragDrop
function.
The DoDragDrop
function starts the drag and drop process.
void OnMouseDown(object sender, MouseEventArgs me)
{
ListBox lb = (ListBox)sender;
int index = lb.IndexFromPoint(me.X,me.Y) ;
if(index >= 0)
{
FileObject item = (FileObject)lb.Items[index];
if(!item.IsFolder)
lb.DoDragDrop(item.NameWithPath,DragDropEffects.Copy);
}
}
DragEnter event
This event is fired when an object is dragged onto the control;the rich edit control in this case.
We will only allow this operation if the dragged data is of type Text
or FileDrop
(dragged from explorer). The DragDropEffects
enumeration allows us to set the effects for the drag and drop operation.
void OnDragEnter(object sender, DragEventArgs de)
{
if(de.Data.GetDataPresent(DataFormats.Text) ||
de.Data.GetDataPresent(DataFormats.FileDrop))
{
de.Effect = DragDropEffects.Copy;
}
else
{
de.Effect = DragDropEffects.None;
}
}
DragDrop event
This event is fired after the dragged object has been dropped over the target control.
We will add follwoing functionality to the eventhandler for this event :
- Read the data if type is
Text
from the dropped object. This text will be the file name with path.
- If the data is of type
FileDrop
then retrieve an array of filenames and use the first entry in the array.
- Set the label's text to this retrieved text.
- Open the file pointed to by this retrieved file name and load its entire contents into the rich edit box.
void OnDragDrop(object sender,DragEventArgs de)
{
StreamReader read;
string fileName = "";
if(de.Data.GetDataPresent(DataFormats.Text))
{
fileName = (string)de.Data.GetData(DataFormats.Text);
}
else if(de.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] fileNames;
fileNames = (string[])de.Data.GetData(DataFormats.FileDrop);
fileName = fileNames[0];
}
fileLabel.Text = fileName;
read = new StreamReader(fileName);
string strb = (string)read.ReadToEnd();
read.Close();
rich.Text = strb;
}
That's it! We are done implementing Drag and Drop functionality.
Implementing help strings
You can add basic help functionality by adding a HelpProvider
control to you form. You can add a helpstring for every control on the form, so that when that control has focus and the user presses F1 key,the form will display the Help text for that control. Here's how you do it...
- Create a
HelpProvider
object for the form.
hlp = new HelpProvider();
- Set the help string for every control by calling the
SetHelpString
method of the HelpProvider
and passing it your control.
- Call the
SetShowHelp
method to enable displaying of help for a control when F1 is pressed.
hlp.SetHelpString(list,"Shows files and folders in the current folder");
hlp.SetShowHelp(list,true);
....
...
..
hlp.SetHelpString(prev,"Click to go to parent folder");
hlp.SetShowHelp(prev,true);
Running the code
I wrote this code using SharpDevelop. You can just compile the MainForm.cs at command prompt if you dont use an IDE.
- Run 2 instances of this application and drap the file from one app to richEdit box of the other. You can see the same functionality in use, using just one instance too.
- Drag a file from Windows Explorer onto the RichEdit box.
- Type a file name in a text editor like wordpad and drag that text to this box.