2010-09-09 90 views
0

我正在构建一个带有拖放支持的Winforms应用程序到TextBox中。 TextBox应该允许将文件和文本放到它上面。它的AllowDrop属性设置为true。调用GetData在DragDrop事件中无提示失败

这是它的DragDrop事件的事件处理程序:

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.GetData(DataFormats.FileDrop); 
    this.textBox.Text = File.ReadAllText(path); 
} 
else if (validText) 
{ 
    var text = (string)e.Data.GetData(typeof(string)); 
    this.textBox.Text = text; 
} 

初试: 当我把这个文本框的文件时,DragDrop事件引发,执行进入我的处理程序,直到这条线(一断点设置在此行上):

var path = (string)e.Data.GetData(DataFormats.FileDrop); 

如果我跳过此指令(F10),则继续执行但不会触发下一条指令。应用程序再次变得响应。就好像该处理程序已中止,但不会引发异常。

第二次测试: 将Visual Studio配置为中断所有异常(在Debug-> Exceptions窗口中查看CLR异常前的Throw框)。 执行与第一次测试相同的操作。你去了,在e.Data.GetData行上引发了一个InvalidCastException(GetData返回一个String [],而不是String)。

我没有AppDomain或线程上的任何一种全局异常处理程序,即使这样做,我会除了在手动跨越失败线时可见的异常。

我正在使用Visual Studio 2010. 任何想法可以解释这种奇怪的行为?这对我很重要,因为如果它不是一个孤立的问题,这可能会导致难以重现的错误。

提前感谢

编辑:真的没有意义,我的事情是,通常未处理的.NET异常崩溃的应用程序。这里的InvalidCastException来自拖放API将一个数组返回给.NET方法的事实,并且我试图在运行时将它转换为一个字符串。此时,该进程正在运行纯粹的.NET代码。为什么只有在未处理的异常自动中断被激活时才会引发异常?

VdesmedT的回答给这件事带来了新的亮点,但它看起来像解释了为什么如果我的应用程序无法处理Drop事件,Explorer不会投诉。

回答

4

在Windows上,拖放操作仍由此旧的OLE处理。 OLE始终将操作的源和目标视为两个不同的应用程序,即使这两个应用程序是相同的应用程序(您的情况)。 OLE总是吞下每个异常,并且不会将它们转发给这两个应用程序中的任何一个。对他而言,在源代码应用程序丢失期间警告源应用程序目标应用程序失败并不明智。去图;-)

你是绝对必须自己处理异常在参与任何OLE操作(即拖动&丢弃)

+0

其实,源是在这种情况下的explorer.exe和目标是我的应用程序。问题在于InvalidCastException在逐步调试期间被吞噬,即使它是纯粹的.NET异常(正如Branimir指出的那样) – 2010-09-09 09:37:28

+0

我接受你的答案,因为它增加了一些有价值的信息,但我仍然不确定。 :) – 2010-09-13 05:08:58

3

e.Data.GetData(DataFormats.FileDrop)处理程序返回一个数组,试试:

var path = ((string[])e.Data.GetData(DataFormats.FileDrop))[0]; 

你应该得到InvalidCastException的,或东西...

+0

你是对的,InvalidCastException在这里引发。我不明白的是为什么异常会被吞噬。 – 2010-09-09 09:38:54