TreeView拖放帮助-_无效的FORMATETC结构_异常
时间:2020-03-05 18:49:33 来源:igfitidea点击:
我正在尝试将拖放功能实现为TreeView控件。当我在节点上启动拖动时,我得到:
无效的FORMATETC结构(HRESULT的异常:0x80040064(DV_E_FORMATETC))
ItemDrag处理程序(发生异常的地方)如下所示:
private void treeView_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e) { this.DoDragDrop(e.Item, DragDropEffects.Move); }
有谁知道这个问题的根本原因以及如何解决? (.NET 2.0,Windows XP SP2)
解决方案
回答
" FORMATETC"是一种应用程序剪贴板,因为缺少更好的用语。为了产生一些在树节点上拖动的视觉技巧,必须将其及其源代码描述复制到此剪贴板中。源代码控件将其信息加载到" FORMATETC"剪贴板中,并将其发送到目标对象。看起来错误发生在放置而不是拖动上。 DV_E_FORMATETC中的DV通常指示放置步骤中发生的错误。
目的地看起来不像我们要投放的目标。剪贴板可能已损坏,或者放置目标的位置可能无法理解它。
我建议我们尝试以下两种方法之一。
- 删除原始的树结构和目标。转储dll。关闭所有内容。打开并将树视图和目标放回窗体。它的格式可能不正确,没有完全填充" FORMATETC"结构。
- 尝试放置另一个树视图并放到该树视图上。如果我们要下降到另一棵树并且它可以工作,则说明橙子对橙子都可以工作,而这不是树视图。如果它是网格或者列表视图,则可能是目的地。我们可能需要更改那些结构才能接收下降。
并非有帮助,但是结构是这样的:
typedef struct tagFORMATETC { CLIPFORMAT cfFormat; DVTARGETDEVICE *ptd; DWORD dwAspect; LONG lindex; DWORD tymed; } FORMATETC, *LPFORMATETC;
回答
使用列表和树视图控件进行拖放时,必须确保正确删除和插入列表项。例如,使用涉及三个ListView控件的拖放操作:
private void triggerInstanceList_DragOver(object sender, DragEventArgs e) { SetDropEffect(e); } private void triggerInstanceList_DragEnter(object sender, DragEventArgs e) { SetDropEffect(e); } private void SetDropEffect(DragEventArgs e) { if (e.Data.GetDataPresent(typeof(ListViewItem))) { ListViewItem itemToDrop = e.Data.GetData(typeof(ListViewItem)) as ListViewItem; if (itemToDrop.Tag is TriggerTypeIdentifier) e.Effect = DragDropEffects.Copy; else e.Effect = DragDropEffects.Move; } else e.Effect = DragDropEffects.None; } private void triggerInstanceList_DragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(ListViewItem))) { try { ListViewItem itemToDrop = e.Data.GetData(typeof(ListViewItem)) as ListViewItem; if (itemToDrop.Tag is TriggerTypeIdentifier) { ListViewItem newItem = new ListViewItem("<new " + itemToDrop.Text + ">", itemToDrop.ImageIndex); _triggerInstanceList.Items.Add(newItem); } else { _expiredTriggers.Items.Remove(itemToDrop); _triggerInstanceList.Items.Add(itemToDrop); } } catch (Exception ex) { Debug.WriteLine(ex); } } }
我们会注意到,在DragDrop事件结束时,我将移动ListViewItem或者创建其中一个的副本。