Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以';我不能在程序的两个实例之间拖动一个点吗?_C#_Winforms_Drag And Drop - Fatal编程技术网

C# 为什么可以';我不能在程序的两个实例之间拖动一个点吗?

C# 为什么可以';我不能在程序的两个实例之间拖动一个点吗?,c#,winforms,drag-and-drop,C#,Winforms,Drag And Drop,我有一个DoDragDrop,我将数据设置为点。当我在一个实例中拖动时,一切都正常。但当我在程序的两个实例之间拖动时,Visual Studio会出现以下错误: 指定的记录无法映射到托管值类 为什么? 编辑:以下是代码: DataObject d = new DataObject(); d.SetData("ThePoint", MyPoint); DragDropEffects e = DoDragDrop(d, DragDropEffects.Move); 以及: 这看起来像一个黑客,但你

我有一个DoDragDrop,我将数据设置为
。当我在一个实例中拖动时,一切都正常。但当我在程序的两个实例之间拖动时,Visual Studio会出现以下错误:

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

为什么?

编辑:以下是代码:

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


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

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);
        }

    }
无法映射指定的记录

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

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

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


创建您自己的类(而不是结构)来存储数据,为其赋予[Serializable]属性,以便可以轻松地封送数据。

请提供更多代码。您在何处以及如何访问数据对象?@dowhilefor补充到问题中。我猜您需要正确序列化该点。我不确定Setdata是如何存储该点的,但我不认为仅仅存储某种引用就存在任何序列化。因此,尝试序列化该点,存储它,并在其他应用程序中反序列化它。可能有一个类型转换器,用于指向和指向字符串,应该可以很好地工作。@dowhilefor听起来不错。如果DragAndDrop只存储一个引用,这就解释了为什么第二个实例无法访问该点本身。谢谢。point是一种值类型,所以我不认为它真的是一种引用,但是一些C#guru可以更好地解释到底发生了什么。因为它不必跨进程边界封送,所以数据对象指针可以直接使用。拖放管道就像一座冰山,90%在水下,看不见。NET事件处理程序很好,但是它们没有显示99%的正在发生的事情。
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);
        }

    }