如何实现将listview中的值比如111,拖拽到picturebox上时,可以选择放置 的位置,即鼠标按下的位置。如果picturebox上已经有了被拖拽过去的数据比如222,实现将111可以放在222的前面或者后面,限制条件是一行最多3个数据,只采纳完整代码答案时间截止今天。
private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
{
ListViewItem item = (ListViewItem)e.Item;
string itemName = item.Text;
listView1.DoDragDrop(itemName, DragDropEffects.Copy);
}
private void listView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effect = DragDropEffects.Copy;
} else
{ e.Effect = DragDropEffects.None; }
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.AllowDrop = true;
}
//判断是不是可以接收的类型
private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
{
e.Effect = DragDropEffects.Copy;
} else
{ e.Effect = DragDropEffects.None; }
}
private List<string> list = new List<string>();
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
string itemName = (string)e.Data.GetData(DataFormats.Text);
list.Add(itemName);
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
for (int i = 0; i < list.Count; i++)
{
itemName = list[i];
int row = i / 3;
int col = i % 3;
g.DrawString(itemName, new Font("Arial", 15), Brushes.Red, new Point(10 + col * 50, 10 + row * 30));
//Graphics p = pictureBox1.CreateGraphics();
//Font font = new Font("Arila", 15);
}
pictureBox1.Image = bmp;
Point mousePosition = pictureBox1.PointToClient(new Point(e.X, e.Y));
}
基于最新版ChatGPT4的回答,望采纳!!!有其他问题也可以询问我哦、”(最新版更智能,功能更加强大)
为了实现拖拽后的数据在PictureBox上根据鼠标位置进行放置,以及实现数据之间的交换位置功能,您需要对现有代码进行一些修改。以下是修改后的完整代码:
private List<string> list = new List<string>();
private int maxItemsPerRow = 3;
private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
{
ListViewItem item = (ListViewItem)e.Item;
string itemName = item.Text;
listView1.DoDragDrop(itemName, DragDropEffects.Copy);
}
private void listView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.AllowDrop = true;
}
private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
string itemName = (string)e.Data.GetData(DataFormats.Text);
Point mousePosition = pictureBox1.PointToClient(new Point(e.X, e.Y));
int targetIndex = GetTargetIndex(mousePosition);
if (targetIndex < list.Count)
{
list.Insert(targetIndex, itemName);
}
else
{
list.Add(itemName);
}
RedrawPictureBox();
}
private int GetTargetIndex(Point mousePosition)
{
int row = (mousePosition.Y - 10) / 30;
int col = (mousePosition.X - 10) / 50;
return row * maxItemsPerRow + col;
}
private void RedrawPictureBox()
{
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
for (int i = 0; i < list.Count; i++)
{
string itemName = list[i];
int row = i / maxItemsPerRow;
int col = i % maxItemsPerRow;
g.DrawString(itemName, new Font("Arial", 15), Brushes.Red, new Point(10 + col * 50, 10 + row * 30));
}
pictureBox1.Image = bmp;
}
在这个修改后的代码中,我添加了一个名为GetTargetIndex
的方法,用于计算拖拽数据应该放置在列表中的位置。此外,还将重绘PictureBox的功能移至名为RedrawPictureBox
的单独方法中。
原有 list 定义改变,准确的x坐标我没计算,也没用上,如果同一行插入数据,自行修改吧
private List<List<string>> list = new List<List<string>>();
private void PictureBox1_DragDrop(object sender, DragEventArgs e)
{
int posX = e.X - ((PictureBox)sender).Left - this.Left;
// posY 的计算自行修改,我这里简单的计算了一下,不是很准确,有误差,需要再减去边框的宽度,我懒得计算了
int posY = e.Y - ((PictureBox)sender).Top - this.Top - (this.Height - this.ClientRectangle.Height);
int row = 0;
string itemName = (string)e.Data.GetData(DataFormats.Text);
// 根据坐标计算出是否需要加行
if (posY > list.Count * 24)
{
list.Add(new List<string>());
row = list.Count - 1;
}
else
{
row = Convert.ToInt32((posY - 1) / 24);
}
// 在当前行添加内容
list[row].Add(itemName);
// 循环行,检查是否有超出长度的行,如果有,则移动到下移行,如果放不下,则加新行
{
List<string> tmp = new List<string>();
for (int i = 0; i < list.Count; i++)
{
tmp.AddRange(list[i]);
}
list = new List<List<string>>();
for (int i = 0; i < tmp.Count; i++)
{
int _row = Convert.ToInt32(i / 3);
if (list.Count == _row)
{
list.Add(new List<string>());
}
list[_row].Add(tmp[i]);
}
}
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
for (int i = 0; i < list.Count; i++)
{
itemName = String.Join(" ", list[i]);
g.DrawString(itemName, new Font("Arial", 10), Brushes.Red, new Point(10, 10 + i * 24));
}
//g.DrawString(itemName, new Font("Arial", 10), Brushes.Red, new Point(10,10));
pictureBox1.Image = bmp;
}
https://www.zhangshengrong.com/p/q0arZ4vkax/
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,我们需要定义一个方法,该方法可以将传入的字符串列表按行列格式绘制到图片上。每行最多放置三个数据,超过三个则自动换行。
private void DrawItems(List<string> items, Graphics g)
{
const int MaxColumns = 3;
const int MaxRows = 3;
const int ItemWidth = 50;
const int ItemHeight = 30;
int index = 0;
for (int row = 0; row < MaxRows; row++)
{
for (int col = 0; col < MaxColumns && index < items.Count; col++)
{
string item = items[index++];
g.DrawString(item, new Font("Arial", 15), Brushes.Red, new Point(10 + col * ItemWidth, 10 + row * ItemHeight));
}
}
}
然后,在pictureBox1的DragDrop事件中,我们需要实现将拖拽过来的项插入到list中,并根据新的list绘制图片。具体操作如下:
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
string itemName = (string)e.Data.GetData(DataFormats.Text);
// 添加项到list
list.Add(itemName);
// 绘制图片
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
DrawItems(list, g);
pictureBox1.Image = bmp;
// 记录鼠标按下的位置
lastMousePosition = pictureBox1.PointToClient(new Point(e.X, e.Y));
}
另外,我们需要在pictureBox1的MouseMove事件中,检测鼠标是否按下并移动,如果按下并移动,则需要实现拖拽交换位置的功能。具体操作如下:
private Point lastMousePosition = Point.Empty;
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && lastMousePosition != Point.Empty)
{
// 计算鼠标移动的偏移量
int dx = e.X - lastMousePosition.X;
int dy = e.Y - lastMousePosition.Y;
// 查找拖动的项在list中的索引
int index = -1;
for (int i = 0; i < list.Count; i++)
{
string item = list[i];
Rectangle rect = new Rectangle(10 + (i % 3) * 50, 10 + (i / 3) * 30, 50, 30);
if (rect.Contains(lastMousePosition))
{
index = i;
break;
}
}
if (index >= 0)
{
// 更新拖动的项的位置
int newIndex = index + dx / 50 + dy / 30 * 3;
if (newIndex < 0)
{
newIndex = 0;
}
if (newIndex >= list.Count)
{
newIndex = list.Count - 1;
}
if (newIndex != index)
{
string item = list[index];
list.RemoveAt(index);
list.Insert(newIndex, item);
lastMousePosition = new Point(lastMousePosition.X + dx, lastMousePosition.Y + dy);
// 更新图片
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
DrawItems(list, g);
pictureBox1.Image = bmp;
}
}
}
}
上面的代码中,我们首先计算了鼠标移动的偏移量 dx 和 dy,然后查找拖动的项在list中的索引。如果找到了索引,我们就按照偏移量计算出新的索引,并更新list。最后,我们更新图片以反映出新的顺序。
完整代码如下:
private List<string> list = new List<string>();
private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
{
ListViewItem item = (ListViewItem)e.Item;
string itemName = item.Text;
listView1.DoDragDrop(itemName, DragDropEffects.Copy);
}
private void listView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.AllowDrop = true;
}
private void DrawItems(List<string> items, Graphics g)
{
const int MaxColumns = 3;
const int MaxRows = 3;
const int ItemWidth = 50;
const int ItemHeight = 30;
int index = 0;
for (int row = 0; row < MaxRows; row++)
{
for (int col = 0; col < MaxColumns && index < items.Count; col++)
{
string item = items[index++];
g.DrawString(item, new Font("Arial", 15), Brushes.Red, new Point(10 + col * ItemWidth, 10 + row * ItemHeight));
}
}
}
private Point lastMousePosition = Point.Empty;
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
string itemName = (string)e.Data.GetData(DataFormats.Text);
// 添加项到list
list.Add(itemName);
// 绘制图片
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
DrawItems(list, g);
pictureBox1.Image = bmp;
// 记录鼠标按下的位置
lastMousePosition = pictureBox1.PointToClient(new Point(e.X, e.Y));
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && lastMousePosition != Point.Empty)
{
// 计算鼠标移动的偏移量
int dx = e.X - lastMousePosition.X;
int dy = e.Y - lastMousePosition.Y;
// 查找拖动的项在list中的索引
int index = -1;
for (int i = 0; i < list.Count; i++)
{
string item = list[i];
Rectangle rect = new Rectangle(10 + (i % 3) * 50, 10 + (i / 3) * 30, 50, 30);
if (rect.Contains(lastMousePosition))
{
index = i;
break;
}
}
if (index >= 0)
{
// 更新拖动的项的位置
int newIndex = index + dx / 50 + dy / 30 * 3;
if (newIndex < 0)
{
newIndex = 0;
}
if (newIndex >= list.Count)
{
newIndex = list.Count - 1;
}
if (newIndex != index)
{
string item = list[index];
list.RemoveAt(index);
list.Insert(newIndex, item);
lastMousePosition = new Point(lastMousePosition.X + dx, lastMousePosition.Y + dy);
// 更新图片
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
DrawItems(list, g);
pictureBox1.Image = bmp;
}
}
}
}
如果我的回答解决了您的问题,请采纳!
不知道你这个问题是否已经解决, 如果还没有解决的话: