【问题标题】:TreeView Drag & Drop help - _Invalid FORMATETC structure_ exceptionTreeView 拖放帮助 - 无效的 FORMATETC 结构异常
【发布时间】:2008-09-08 18:17:53
【问题描述】:

我正在尝试使用作为 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)

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    如果它对其他人有帮助 - 我在 WPF TreeView(不是问题中列出的 Windows 窗体)遇到了这个问题,解决方案只是确保将事件标记为在 drop 事件处理程序中处理。

        private void OnDrop(object sender, DragEventArgs e)
        {
            // Other logic...
    
            e.Handled = true;
        }
    

    【讨论】:

      【解决方案2】:

      FORMATETC 是一种应用剪贴板,因为没有更好的术语。为了实现一些在树节点周围拖动的视觉技巧,必须将其复制到此剪贴板及其源描述中。源代码管理将其信息加载到FORMATETC 剪贴板并将其发送到目标对象。看起来错误发生在放置而不是拖动上。 DV_E_FORMATETC 中的 DV 通常表示放置步骤中发生的错误。
      目的地看起来不像你在上面放的东西。剪贴板可能已损坏,或者放置目标可能未配置为理解它。

      我建议您尝试以下两种方法之一。

      1. 删除原始树结构和目标。转储你的dll。关闭一切。打开并将树视图和目的地放回表单上。它可能只是形成不良并且没有完全填充FORMATETC 结构。
      2. 尝试放置另一个树视图,然后放在那里。如果你掉到另一棵树上并且它工作你知道你的橙子到橙子工作,它不是树视图。如果它是网格或列表视图,它可能是目的地。您可能需要更改这些结构才能接收掉落物。

      不是说它有帮助,而是结构是这样的:

      typedef struct tagFORMATETC
      {
        CLIPFORMAT      cfFormat;
        DVTARGETDEVICE  *ptd;
        DWORD           dwAspect;
        LONG            lindex;
        DWORD           tymed;
      } FORMATETC, *LPFORMATETC;
      

      【讨论】:

      • 您误解了答案。这就是 FORMATETC 在 Windows 中的构造方式。答案的代码不是答案,而是如何构建有错误的对象。剪贴板不是用 C# 编写的,它是用 C++ 编写的,并且是 Windows 的一部分。该错误是 Windows 本地的,并且该对象中没有 C# 代码。这是有错误的对象的代码。我的回答是代码上方的文字。解决方案是用较新的库替换 .DLL。
      【解决方案3】:

      使用列表和树视图控件进行拖放时,您必须确保正确删除和插入列表项。例如,使用涉及三个 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,要么创建一个副本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-15
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多