我怎样才能推迟这一点;渲染“;Winforms跨进程拖放期间我的数据对象的

我怎样才能推迟这一点;渲染“;Winforms跨进程拖放期间我的数据对象的,winforms,drag-and-drop,ole,Winforms,Drag And Drop,Ole,我有一个对象,虽然它有一个文本表示(即可以存储在大约1000个可打印字符的字符串中),但生成它的成本很高。我还有一个树控件,它显示对象的“摘要”。我不仅希望在自己的应用程序中拖放这些对象,还希望将这些对象拖放到接受CF_TEXT或CF_UNICODETEXT的其他应用程序中,此时文本表示将插入到拖放目标中 我一直在考虑延迟“呈现”对象的文本表示,以便仅当对象被拖放或粘贴时才会发生。然而,Winforms似乎在拖动开始时急切地调用GetData()方法,这会在拖动开始时造成痛苦的几秒钟延迟 有没有

我有一个对象,虽然它有一个文本表示(即可以存储在大约1000个可打印字符的字符串中),但生成它的成本很高。我还有一个树控件,它显示对象的“摘要”。我不仅希望在自己的应用程序中拖放这些对象,还希望将这些对象拖放到接受CF_TEXT或CF_UNICODETEXT的其他应用程序中,此时文本表示将插入到拖放目标中

我一直在考虑延迟“呈现”对象的文本表示,以便仅当对象被拖放或粘贴时才会发生。然而,Winforms似乎在拖动开始时急切地调用GetData()方法,这会在拖动开始时造成痛苦的几秒钟延迟


有没有办法确保GetData()只在删除时发生?或者,在Winforms程序中实现此延迟删除机制的正确机制是什么?

经过一些研究,我能够想出如何做到这一点,而不必实现COM接口
IDataObject
(及其所有
FORMATETC
gunk)。我认为这可能会引起其他处于同样困境的人的兴趣,所以我写下了我的解决方案。如果能做得更聪明些,我会全神贯注的

System.Windows.Forms.DataObject
类具有以下构造函数:

public DataObject(string format, object data)
我这样称呼它:

string expensive = GenerateStringVerySlowly();
var dataObject = new DataObject(
    DataFormats.UnicodeText,
    expensive);
DoDragDrop(dataObject, DragDropEffects.Copy);
string expensive = GenerateStringVerySlowly();    
var dataObject = new DataObject(
    DataFormats.UnicodeText,
    new MemoryStream(Encoding.Unicode.GetBytes(expensive)));
DoDragDrop(dataObject, DragDropEffects.Copy);
上述代码将在复制操作期间将字符串数据放入
HGLOBAL
。但是,您也可以这样调用构造函数:

string expensive = GenerateStringVerySlowly();
var dataObject = new DataObject(
    DataFormats.UnicodeText,
    expensive);
DoDragDrop(dataObject, DragDropEffects.Copy);
string expensive = GenerateStringVerySlowly();    
var dataObject = new DataObject(
    DataFormats.UnicodeText,
    new MemoryStream(Encoding.Unicode.GetBytes(expensive)));
DoDragDrop(dataObject, DragDropEffects.Copy);
与通过
HGLOBAL
复制数据不同,后面的调用具有通过(COM)
IStream
复制数据的良好效果。显然,.NET互操作层正在发挥某种魔力,它处理COM
IStream
和.NET
System.IO.Stream
之间的映射

我现在所要做的就是编写一个类,将流的创建推迟到最后一分钟(),当drop目标开始调用
Length
Read
等时。它看起来是这样的:(为简洁起见编辑了部分)

这正是我所需要的,使这项工作。然而,我在这里依赖于下降目标的良好行为。行为不端的drop目标急切地调用
Read
方法,会导致代价高昂的操作提前发生