为什么我不能在程序的两个实例之间拖动一个Point?

时间:2012-06-11 12:13:48

标签: c# winforms drag-and-drop

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

  

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

为什么?

编辑:这是代码:

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

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

2 个答案:

答案 0 :(得分:4)

  

无法映射指定的记录

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

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

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

创建自己的类(不是struct)来存储数据,给它[Serializable]属性,以便它可以被轻松编组。

答案 1 :(得分: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);
        }

    }