【问题标题】:C# .NET 4.0 Drag and drop between two applicationsC# .NET 4.0 在两个应用程序之间拖放
【发布时间】:2014-05-25 08:11:03
【问题描述】:

所以我真的很想在应用程序的两个实例之间拖放数据;但是,如果在我要放置的目标点存在数据,我想将该数据与正在放置的数据交换。

我正在尝试使用 MemoryMappedFIle,这似乎在大多数情况下都有效,但并不完美。例如,如果我拖/放得太快,目标数据就会被简单地覆盖(我假设它没有足够快地写入 MemoryMappedFile)。有人有什么建议吗?

这是我目前拥有的:

    private void pbSprite_MouseDown(object sender, MouseEventArgs e)
    {
        PictureBox pb = (PictureBox)(sender);
        DataObject data = new DataObject();
        if (pb.Name == pbSprite.Name)
        {
            data = new DataObject(DataFormats.Serializable, frmpkm);
        }
        else
        {
            data = new DataObject(DataFormats.Serializable, frmpkm2);
        }
        pb.DoDragDrop(data, DragDropEffects.Move);
        MemoryMappedFile MemoryMapped = MemoryMappedFile.CreateOrOpen("name", 1000, MemoryMappedFileAccess.ReadWrite);
        using (MemoryMappedViewAccessor FileMap = MemoryMapped.CreateViewAccessor())
        {
            PKMDS.Pokemon otherpkm = new PKMDS.Pokemon();
            for (int i = 0; i < Marshal.SizeOf(otherpkm); i++)
            {
                FileMap.Read<byte>(i, out otherpkm.Data[i]);
            }
            if (pb.Name == pbSprite.Name)
            {
                frmpkm.Data = otherpkm.Data;
            }
            else
            {
                frmpkm2.Data = otherpkm.Data;
            }
            lblData.Text = frmpkm.SpeciesName;
            lblData2.Text = frmpkm2.SpeciesName;
            pbSprite.Image = frmpkm.Sprite;
            pbSprite2.Image = frmpkm2.Sprite;
        }
    }
    private void pbSprite_DragDrop(object sender, DragEventArgs e)
    {
        if (e.Data != null)
        {
            PictureBox pb = (PictureBox)(sender);
            PKMDS.Pokemon otherpkm = (PKMDS.Pokemon)e.Data.GetData(DataFormats.Serializable);
            MemoryMappedFile MemoryMapped = MemoryMappedFile.CreateOrOpen("name", 1000, MemoryMappedFileAccess.ReadWrite);
            using (MemoryMappedViewAccessor FileMap = MemoryMapped.CreateViewAccessor())
            {
                for (int i = 0; i < Marshal.SizeOf(frmpkm); i++)
                {
                    if (pb.Name == pbSprite.Name)
                    {
                        FileMap.Write<byte>(i, ref frmpkm.Data[i]);
                    }
                    else
                    {
                        FileMap.Write<byte>(i, ref frmpkm2.Data[i]);
                    }
                }
            }
            if (pb.Name == pbSprite.Name)
            {
                frmpkm.Data = otherpkm.Data;
            }
            else
            {
                frmpkm2.Data = otherpkm.Data;
            }
            lblData.Text = frmpkm.SpeciesName;
            lblData2.Text = frmpkm2.SpeciesName;
            pbSprite.Image = frmpkm.Sprite;
            pbSprite2.Image = frmpkm2.Sprite;
        }
    }

【问题讨论】:

  • 一个 MMF 是一个 very 低级互操作对象。您必须始终将自己的同步添加到与正在访问 MMF 的任何其他代码的握手中。你的程序出错了,因为你没有任何数据,你从来没有确保你写的最后一个数据被读取了。所以不要使用 MMF,在托管代码中通常没有什么意义,而是使用命名管道或套接字。或 WCF,使这变得容易。或者只是简单的拖放,已经用于跨进程边界复制数据。

标签: c# .net drag-and-drop


【解决方案1】:

两种可能的尝试

在创建内存映射文件后将调用移至pb.DoDragDrop(data, DragDropEffects.Move);。这将导致拖/放操作开始延迟,但应确保数据已写入文件。

另一种选择是在单独的线程中将数据写入 mmf,并在写入数据时设置它和 Event。然后pbSprite_DragDrop 可以等待事件发出信号,然后再从文件中读取。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多