TreeView Drag&删除帮助 - _Invalid FORMATETC structure_ exception

时间:2008-09-08 18:17:54

标签: c# .net winforms

我正在尝试实施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)

3 个答案:

答案 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通常表示丢弃步骤中发生错误 目的地看起来不像你喜欢的东西。剪贴板可能已损坏,或者可能未配置放置目标以了解它。

我建议你尝试两件事之一。

  1. 删除原始树结构和目标。转储你的dll。关闭一切。打开并将树视图和目的地放回到表单上。它可能刚刚形成不良而且没有完全填充FORMATETC结构。
  2. 尝试将另一个树视图放到那里。如果你正在摔到另一棵树上并且它有效,你会知道你的橙子到橘子的工作,而不是树视图。如果它是网格或列表视图,它可能是目的地。您可能需要更改这些结构以便能够接收丢弃。
  3. 不是它有帮助,但结构是这样的:

    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,要么创建一个副本。