Call to GetData fails silently in DragDrop event
I am building a Winforms application with drag and drop support into a TextBox. The TextBox should allow files and text to be dropped onto it. Its AllowDrop property is set to true.
This is the event handler for its DragDrop event:
var validFile = e.Data.GetDataPresent(DataFormats.FileDrop);
var validText = e.Data.GetDataPresent(DataFormats.Text) ||
e.Data.GetDataPresent(DataFormats.UnicodeText);
if (validFile)
{
var path = (string)e.Data.Ge开发者_如何学GotData(DataFormats.FileDrop);
this.textBox.Text = File.ReadAllText(path);
}
else if (validText)
{
var text = (string)e.Data.GetData(typeof(string));
this.textBox.Text = text;
}
First test: When I drop a file on this TextBox, the DragDrop event is raised, execution goes into my handler until this line (a breakpoint is set on this line):
var path = (string)e.Data.GetData(DataFormats.FileDrop);
If I step over this instruction (F10), execution continues but never hit the next instruction. The application become responsive again. It is as if the handler is aborted but no exception is raised.
Second test: Configure Visual Studio to break on all Exceptions (check the Throw box in front of the CLR exceptions in the Debug->Exceptions window). Perform same actions as in the first test. And there you go, an InvalidCastException is raised on the e.Data.GetData line (GetData returns a String[], not a String).
I don't have any kind of global exception handler on AppDomain or threads, and even if did, I would except the exception to be visible when manually stepping over the failing line.
I am using Visual Studio 2010. Any idea that would explain this strange behavior? This is important to me because if it is not an isolated issue, this can lead to hard-to-reproduce bugs.
Many thanks in advance
EDIT: The thing that really does not make sense to me is that usually unhandled .NET exception crashes the application. Here the InvalidCastException comes from the fact that the Drag&Drop API returns an array to the .NET method, and I try to cast it at runtime into a string. At that point, the process is running purely .NET code. Why would it raise the exception only when automatic break on unhandled exceptions is activated?
VdesmedT's answer bring a new light to the matter but it looks like it explains why Explorer would not complain if my application failed to process the Drop event.
On Windows, the drag and drop operation are still handled by this good old OLE. OLE Always sees the source and the target of the operation as two different applications even when the two are the same application (your case). OLE always swallows every exception and no not forward them to any of the two application. For him, it does not make sens to alert the source application that the target application failed during the drop. go figure ;-)
You absolutly have to handle exception yourself in the handlers involved in any OLE operation (i.e. Drag & Drop)
e.Data.GetData(DataFormats.FileDrop) returns an array, try:
var path = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];
You should get InvalidCastException, or something...
精彩评论