TreeView fires DragEnter, DragOver and DragLeave events, but won't fire DragDrop
Hail Stack!
I'm having a hard time trying to figure out why my treeview (or any other component, even the form itself) won't fire the event DragDrop.
I've settled my form like this:
A Form with a Panel inside. The Panel have a TreeView, and this TreeView (MyTree) has the following code:MyTree.AllowDrop = true;
MyTree.DragDrop += new System.Windows.Forms.DragEventHandler(onDragDrop);
MyTree.DragEnter += new System.Windows.Forms.DragEventHandler(onDragEnter);
MyTree.DragLeave += new System.EventHandler(onDragLeave);
MyTree.DragOver += new System.Windows.Forms.DragEventHandler(onDragOver);
The handlers looks like this:
private void onDragEnter(object sender, DragEventArgs e)
{
Console.WriteLine(" === DragEnte开发者_高级运维r === ");
}
private void onDragLeave(object sender, EventArgs e)
{
Console.WriteLine(" === DragLeave === ");
}
private void onDragOver(object sender, DragEventArgs e)
{
Console.WriteLine(" === DragOver === ");
}
private void onDragDrop(object sender, DragEventArgs e)
{
Console.WriteLine(" === DragDrop === ");
}
When I test my app, dragging a *.txt file (or anything) the output are something like:
=== DragEnter ===
=== DragOver ===
=== DragOver ===
...
=== DragOver ===
=== DragLeave ===
The last line ( === DragLeave === ) wasn't meant to be a leave event.
In fact, this line is printed when I release the mouse button over my TreeView.I'm I doing something terribly wrong?
this is what I use for drag and drop to a treeview for files:
public class DragDropManager
{
private UserControl _parent;
private AddFilesEventHandler OnAddFiles;
public DragDropManager()
{
}
public UserControl Parent
{
set
{
_parent = value;
if ( ! ( _parent is IDropFileTarget ) )
{
throw new Exception("DragDropManager: Parent usercontrol does not implement IDropFileTarget interface");
}
OnAddFiles = new AddFilesEventHandler(((IDropFileTarget)_parent).AddFiles);
_parent.AllowDrop = true;
_parent.DragEnter += new System.Windows.Forms.DragEventHandler(this.OnDragEnter);
_parent.DragDrop += new System.Windows.Forms.DragEventHandler(this.OnDragDrop);
}
}
/// <summary>
/// Handle parent form DragEnter event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
string[] formats = e.Data.GetFormats(true);
//e.Effect = DragDropEffects.All;
for (int formatIndex = 0; formatIndex < formats.Length; formatIndex++)
{
switch (formats[formatIndex])
{
case Consts.DragDropFormats.FileDrop:
e.Effect = DragDropEffects.Copy;
break;
case Consts.DragDropFormats.Text:
e.Effect = DragDropEffects.Move;
break;
case Consts.DragDropFormats.UniformResourceLocator:
e.Effect = DragDropEffects.Link;
break;
}
}
}
/// <summary>
/// Handle parent form DragDrop event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
try
{
string[] formats = e.Data.GetFormats(true);
string[] values = new string[1];
string url = string.Empty;
for (int formatIndex = 0; formatIndex < formats.Length; formatIndex++)
{
switch (formats[formatIndex])
{
case Consts.DragDropFormats.FileDrop:
Array itemList = (Array)e.Data.GetData(Consts.DragDropFormats.FileDrop);
if (itemList != null)
{
_parent.BeginInvoke(OnAddFiles, new Object[] { itemList });
_parent.Focus();
}
break;
case Consts.DragDropFormats.Text:
case Consts.DragDropFormats.UniformResourceLocator:
values[0] = e.Data.GetData(Consts.DragDropFormats.Text).ToString();
_parent.BeginInvoke(OnAddFiles, new Object[] { values });
_parent.Focus();
break;
default:
break;
}
}
}
catch (Exception ex)
{
Trace.WriteLine("Error in DragDropManager.OnDragDrop function: " + ex.Message);
}
}
}
you can use it as follows:
DragDropManager dragDropManager = new DragDropManager();
dragDropManager.Parent = this;
and need to implement this on the UserControl
public interface IDropFileTarget
{
void AddFiles(Array Files);
}
You need to set e.Effect
in DragOver
to something other than None
to tell the system that you're willing to be dropped on.
You need to make sure the dragged item actually has some data in it. Get a string array of what's present using
e.Data.GetFormats()
Use each element of the string array 'fmt' as an argument to GetData
e.Data.GetData(fmt)
If they're all null, it's not going to fire the DragDrop event and no amount of setting e.Effect is going to change that. If you determine this to be the cause, you can be more specific in searching for the root cause. (in my case, Internet Explorer)
精彩评论