5

我有一个 DoDragDrop,我在其中将数据设置为Point.when 我在一个实例中拖动 - 一切正常。但是当我在程序的两个实例之间拖动时,Visual Studio 给了我这个错误:

指定的记录无法映射到托管值类。

为什么?

编辑:这是代码:

DataObject d = new DataObject();
d.SetData("ThePoint", MyPoint);
DragDropEffects e = DoDragDrop(d, DragDropEffects.Move);

和:

Point e2 = (Point)e.Data.GetData("ThePoint");
4

2 回答 2

4

无法映射指定的记录

请注意“记录”一词的奇怪之处。它是“结构”的以 COM 为中心的词。你试图做的几乎可以工作,但并不完全。DoDragDrop() 方法将 Point 结构正确地编组为 COM 对象,这可能是因为 Point 具有 [ComVisible(true)] 属性。缺少的成分是 IRecordInfo 所需的信息,IRecordInfo 是一个描述结构布局的 COM 接口。必需,因为结构具有非常依赖于编译器的布局。

该接口通常通过从类型库中读取结构定义来实现。这实际上是可用的,Point 结构在 c:\windows\microsoft.net\framework\v2.0.50727\system.drawing.tlb 中进行了描述。您可以使用 OleView.exe 工具 File + View Typelib 查看它。

一切都很好,除了 COM 对象的接收者必须将其转换回托管对象的部分,即点。这需要找出包含对象定义的类型库,以便 IRecordInfo 可以完成其工作。其中记录在注册表中,HKCR\Record 键。其中不包含Point 的条目。卡布姆。

创建你自己的类(不是结构)来存储数据,给它 [Serializable] 属性,这样它就可以被简单地编组。

于 2012-06-11T13:34:19.857 回答
1

这看起来像一个黑客,但你可以做到这一点,我测试了它的工作原理。 编辑 猜猜它没有回答为什么?问题。

private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
        Point MyPoint = new Point(100, 200);
        DoDragDrop(new string[] { MyPoint.X.ToString(), MyPoint.Y.ToString() }, DragDropEffects.Copy);
    }

    private void Form1_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Copy;
    }

    private void Form1_DragDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(typeof(string[])))
        {
            string[] item = (string[])e.Data.GetData(typeof(string[]));
            Point e2 = new Point(Int32.Parse(item[0]), Int32.Parse(item[1]));

            MessageBox.Show(e2.X+":"+e2.Y);
        }

    }
于 2012-06-11T13:09:00.860 回答