How to drag images from a listview (together with an imageview) to pictureboxes?

孤者浪人 提交于 2019-12-13 04:08:41

问题


I am pretty new to C# and struggle a lot with a small project I want to do.

I am busy with something like a collage maker where I have a list of pictures on the left hand side and I want to drag and drop multiple images to the right hand side where I want to be able to move them around to create my collage.

I wanted to show an image but I am not allowed to post images with less than 10 reputation points. But look here for the image:

I can't manage to get it to work. I've looked online for help but I can't really find what I'm looking for. The stuff I do find are too unclear and I struggle to understand.

This is what I have so far for the code to drag and drop from the left to the right but it doesn't work;

private void pictureBox1_DragEnter(object sender, DragEventArgs e)
    {
        int len = e.Data.GetFormats().Length - 1;
        int i;
        for (i = 0; i <= len; i++)
        {
            if (e.Data.GetFormats()[i].Equals("System.Windows.Forms.ListView+SelectedListViewItemCollection"))
            {
                //The data from the drag source is moved to the target.
                e.Effect = DragDropEffects.Move;
            }
        }
    }

    private void pictureBox1_DragDrop(object sender, DragEventArgs e)
    {
        //Return if the items are not selected in the ListView control.
        if (listView1.SelectedItems.Count == 0)
        {
            return;
        }
        ListViewItem dragitem = listView1.SelectedItems[0];
        pictureBox2.Image = imageList1.Images[dragitem.ImageIndex];
        listView1.Items.Remove(dragitem);
    }

    private void listView1_MouseDown(object sender, MouseEventArgs e)
    {
        listView1.DoDragDrop(listView1.SelectedItems, DragDropEffects.Move);
    }

And after I can add image to the left, how can I drag and move them around using the mouse coordinates?

Any help will be appreciated please. Everything is done using C# in Windows Forms.


回答1:


Here is a full example you may want to play with:

It uses a form with a ListView, an ImageList and a Panel to hold the PictureBoxes.

You could use a FlowLayoutPanel but this won't let you move the Pictureboxes later.

You also could use a grid of Panels and their BackgroundImage.

First we set up the form:

private void Form1_Load(object sender, EventArgs e)
{
    KeyPreview = true;
    FillLV(10);
    AddPBs(36);
    listView1.MouseMove += listView1_MouseMove;
}

void FillLV(int count)
{
    for (int i = 0; i < count; i++) listView1.Items.Add("Item" + i, i);
}

void AddPBs(int count)
{
    int iWidth = imageList1.ImageSize.Width;
    int iHeight = imageList1.ImageSize.Height;
    int cols = panel1.ClientSize.Width / iWidth;

    for (int i = 0; i < count; i++)
    {
        PictureBox PB = new PictureBox();
        PB.BackColor = Color.LightGray;
        PB.Margin = new System.Windows.Forms.Padding(0);
        PB.ClientSize = new System.Drawing.Size(iWidth , iHeight );
        PB.Location = new Point(iWidth * (i % cols), iHeight * (i / cols));
        PB.Parent = panel1;
        PB.DragEnter += PB_DragEnter;
        PB.DragDrop += PB_DragDrop;
        PB.AllowDrop = true;
        PB.MouseClick += (ss, ee) => { currentPB = PB; PB.Focus(); };
    }
}

Note how we add events to the dynamically created PictureBoxes and how we set their hidden AllowDrop property.

Also note the little lambda to make the MouseClick prepare for moving them around with the keyboard.

For this we will also need a reference to the current box:

PictureBox currentPB = null;

Now we start the dragging. This should not be done in the MouseDown or else it will interfere with normal selection and also happen before the new selection is made..

Either you do it in the MouseMove:

void listView1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        if (listView1.SelectedItems.Count > 0)
        {
            listView1.DoDragDrop(listView1.SelectedItems[0], DragDropEffects.Move);
        }
    }
}

Or (Update) for ListViews better and much simpler (thanks Hans!) in their ItemDrag event:

private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
{
    listView1.DoDragDrop(e.Item, DragDropEffects.Move);
}

Update: Both ways now use the dragged Item, not just its imageIndex, to make it simpler to remove the Item from the LV..

void PB_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(ListViewItem))) 
        e.Effect = DragDropEffects.Move;
    else
        e.Effect = DragDropEffects.None;
}

void PB_DragDrop(object sender, DragEventArgs e)
{
    PictureBox pb = sender as PictureBox;
    var item = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
    int index = item.ImageIndex;
    pb.Image = imageList1.Images[index];  // make sure you have images for indices!!

}

Finally we use the keyboard to move the current box around. I have added code to bring it up and down in the z-order as well.

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (currentPB == null) return;
    if (e.KeyData == Keys.Left) currentPB.Left -= 1;
    else if (e.KeyData == Keys.Right) currentPB.Left += 1;
    else if (e.KeyData == Keys.Up) currentPB.Top -= 1;
    else if (e.KeyData == Keys.Down) currentPB.Top += 1;
    else
    { 
        int z = panel1.Controls.GetChildIndex(currentPB);
        if (e.KeyData == Keys.Home) panel1.Controls.SetChildIndex(currentPB, 0);
        else if (e.KeyData == Keys.End) 
             panel1.Controls.SetChildIndex(currentPB, panel1.Controls.Count);
        else if (e.KeyData == Keys.PageUp) 
             panel1.Controls.SetChildIndex(currentPB, z + 1);
        else if (e.KeyData == Keys.PageDown) 
             { if (z > 0) panel1.Controls.SetChildIndex(currentPB, z - 1); }
    }
    panel1.Invalidate();

}

For this to work the form must have : KeyPreview = true;

Note that the sizes in an ImageList are restricted to 256x256. So you may want to use only the index and use it to load larger images from disk..



来源:https://stackoverflow.com/questions/32920767/how-to-drag-images-from-a-listview-together-with-an-imageview-to-pictureboxes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!