我正在使用c#3.5 / winforms
在我的表格中,我在面板中有2个图片框PB1和PB2(以及许多其他控件)。 用户可以将PB1拖到PB2。但他也可以通过在表单上或表单外的任何位置释放左键来取消删除。 PB1可以拖动固定次数。当拖动开始时,我减少PB1中的变量,如果它达到0,则PB变得不可见。
但是如果用户取消拖动,PB1必须知道增加变量并设置PB1的可见性。
我的问题是:PB1如何知道拖动被取消(或实际上,甚至在有效控件上被删除)?请记住,用户可以释放窗体外的拖动,因此我无法在窗体上使用Drop事件。我尝试GiveFeedback和QueryContinueDrag事件,但只要拖动继续,它们就会被触发,但是当它停止时它们就会被触发。
一些代码:
class COPGOJetonImage
{
private PictureBox PB1;
public COPGOJetonImage()
{
PB1 = new PictureBox();
//here I initialize PB1
((Control)PB1).AllowDrop = true; //in case of
PB1.MouseDown += OnMouseDown;
}
public void OnMouseDown(object sender, MouseEventArgs ev)
{
PB1.DoDragDrop(PB1.Image, DragDropEffects.Copy);
}
}
答案 0 :(得分:2)
" 有1到4个有效目标。"
在此示例中,我们拖动pictureBox1
,而pictureBox2
至pictureBox5
是有效的放置目标。我们使用自定义名称创建一个DataObject,以便在拖放操作期间封装pictureBox1
。在放置目标中,如果被拖动的东西中存在自定义名称,我们只允许放弃。这确保我们只从pictureBox1
本身获得DragDrop事件,并且我们知道减少我们的丢弃计数器是安全的。我们可以从DataObject中检索pictureBox1
并更改其状态,以便不再删除它:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int DropsLeft = 5;
private string DataFormatName = "YourUniqueDataFormatNameHere";
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseMove += PictureBox1_MouseMove;
PictureBox[] pbs = new PictureBox[] { pictureBox2, pictureBox3, pictureBox4, pictureBox5 };
foreach (PictureBox pb in pbs)
{
pb.AllowDrop = true;
pb.DragEnter += Pb_DragEnter;
pb.DragDrop += Pb_DragDrop;
}
}
private void PictureBox1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
DataObject data = new DataObject(DataFormatName, pictureBox1);
pictureBox1.DoDragDrop(data, DragDropEffects.Copy);
}
}
private void Pb_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormatName))
{
e.Effect = DragDropEffects.All;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void Pb_DragDrop(object sender, DragEventArgs e)
{
DropsLeft--;
// retrieve the data
PictureBox pb = (PictureBox)e.Data.GetData(DataFormatName);
if (DropsLeft == 0)
{
MessageBox.Show("No more drops left!");
pb.Enabled = false;
pb.BackColor = Color.Red; // for visual effect
}
}
}