我正在尝试实施Drag&使用Source作为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)
答案 0 :(得分:2)
如果它帮助其他人 - 我遇到了WPF TreeView的问题(不是问题中列出的Windows窗体),解决方案只是确保将事件标记为在drop事件处理程序中处理。
private void OnDrop(object sender, DragEventArgs e)
{
// Other logic...
e.Handled = true;
}
答案 1 :(得分:1)
FORMATETC
是一种应用程序剪贴板,缺少更好的术语。为了消除树节点周围的一些视觉技巧,必须将其复制到此剪贴板及其源描述。源控件将其信息加载到FORMATETC
剪贴板并将其发送到目标对象。看起来错误发生在拖放上而不是拖动上。 DV
中的DV_E_FORMATETC
通常表示丢弃步骤中发生错误
目的地看起来不像你喜欢的东西。剪贴板可能已损坏,或者可能未配置放置目标以了解它。
我建议你尝试两件事之一。
FORMATETC
结构。不是它有帮助,但结构是这样的:
typedef struct tagFORMATETC
{
CLIPFORMAT cfFormat;
DVTARGETDEVICE *ptd;
DWORD dwAspect;
LONG lindex;
DWORD tymed;
} FORMATETC, *LPFORMATETC;
答案 2 :(得分:1)
使用list和treeview控件进行拖放操作时,必须确保正确删除和插入列表项。例如,使用涉及三个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,要么创建一个副本。