简体   繁体   中英

C# .NET 4.0 Drag and drop between two applications

So I'd really like to drag and drop data between two instances of an application; however, if there is data present at the target point where I am dropping, I would like to swap that data with what is being dropped.

I'm trying to use a MemoryMappedFIle, and that seems to work most of the time, but it's not perfect. For example, if I do the drag / drop too quickly, the target data is simply overwritten (I assume it's not being written to the MemoryMappedFile quickly enough). Does anyone have any recommendations?

This is what I currently have:

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

Two possible things to try

Move the call to pb.DoDragDrop(data, DragDropEffects.Move); after the creation of the memory mapped file. This will cause a delay in the start of the drag/drop action but should ensure that the data has been written to the file.

The other alternative is to write the data to the mmf in a separate thread and have it set and Event when the data is written. Then pbSprite_DragDrop can wait for the event to be signaled before reading from the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM