WPF: Drag and Drop Textbox for Windows Explorer files

There are a lot of places on the web that talk about this concept and it’s clear there are a few ways to create a drag and drop TextBox in WPF.

Here is what I recommend to accomplish this task:

Given:
Your TextBox name is “TextBox1”

C#

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
	public MainWindow()
	{
		// Initialize UI
		InitializeComponent();

		// Loaded event
		this.Loaded += delegate
			{
				TextBox1.AllowDrop = true;
				TextBox1.PreviewDragEnter += TextBox1PreviewDragEnter;
				TextBox1.PreviewDragOver += TextBox1PreviewDragOver;
				TextBox1.Drop += TextBox1DragDrop;
			};
	}

	/// <summary>
	/// We have to override this to allow drop functionality.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void TextBox1PreviewDragOver(object sender, DragEventArgs e)
	{
		e.Handled = true;
	}

	/// <summary>
	/// Evaluates the Data and performs the DragDropEffect
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void TextBox1PreviewDragEnter(object sender, DragEventArgs e)
	{
		if (e.Data.GetDataPresent(DataFormats.FileDrop))
		{
			e.Effects = DragDropEffects.Copy;
		}
		else
		{
			e.Effects = DragDropEffects.None;
		}
	}

	/// <summary>
	/// The drop activity on the textbox.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void TextBox1DragDrop(object sender, DragEventArgs e)
	{
		// Get data object
		var dataObject = e.Data as DataObject;

		// Check for file list
		if (dataObject.ContainsFileDropList())
		{
			// Clear values
			TextBox1.Text = string.Empty;

			// Process file names
			StringCollection fileNames = dataObject.GetFileDropList();
			StringBuilder bd = new StringBuilder();
			foreach (var fileName in fileNames)
			{
				bd.Append(fileName + "\n");
			}

			// Set text
			TextBox1.Text = bd.ToString();
		}
	}
}

Now, let’s look at each event and cover what is going on:

/// <summary>
/// We have to override this to allow drop functionality.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void TextBox1PreviewDragOver(object sender, DragEventArgs e)
{
	e.Handled = true;
}

We need to add this to override the default PreviewDrag behavior. If we don’t, then the Drop Event will not fire.

/// <summary>
/// Evaluates the Data and performs the DragDropEffect
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TextBox1PreviewDragEnter(object sender, DragEventArgs e)
{
	if (e.Data.GetDataPresent(DataFormats.FileDrop))
	{
		e.Effects = DragDropEffects.Copy;
	}
	else
	{
		e.Effects = DragDropEffects.None;
	}
}

This piece deals with the source being dragged over the textbox. The data is evaluated at this point, and the DragDropEffects are executed accordingly. Notice that the data is checked for the correct type.

MSDN breaks down the DragDropEffects here.

/// <summary>
/// The drop activity on the textbox.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TextBox1DragDrop(object sender, DragEventArgs e)
{
	// Get data object
	var dataObject = e.Data as DataObject;

	// Check for file list
	if (dataObject.ContainsFileDropList())
	{
		// Clear values
		TextBox1.Text = string.Empty;

		// Process file names
		StringCollection fileNames = dataObject.GetFileDropList();
		StringBuilder bd = new StringBuilder();
		foreach (var fileName in fileNames)
		{
			bd.Append(fileName + "\n");
		}

		// Set text
		TextBox1.Text = bd.ToString();
	}
}

In the drop event, a few things occur:

  • We grab the DataObject from “e”.
  • Then evaluate the DataObject to ensure it has a StringCollection using GetFileDropList.
  • We grab the StringCollection.
  • We enumerate through the collection and append each filename to a StringBuilder object.
  • Finally, we add the StringBuilder content to the TextBox Text field.
 
Comments

Thank you. This is exactly what I wanted.

Glad I could help Paul.

I regard something genuinely interesting about your weblog so I saved to my bookmarks .

Reblogged this on Technical babble… and commented:

Since this was such a popular post I thought I would share it again.

Brilliant! Just note there should be a “\n” not “n”

Yeah, totally. This is the result of importing from another WordPress setup. It trimmed off the “\” because of special character issues. Thanks for pointing that out.

Leave a Reply