问题
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