是否有一种简单的方法可以确保在拖放操作无法完成后,MouseUp事件不被框架消耗掉并被忽略?
我找到了一篇描述一种机制的博客文章,但它涉及大量的手工簿记,包括状态标志,MouseMove事件,手动"鼠标离开"检查等等.如果它可以,我宁愿不必实施所有这些.避免.
我最近想在我的项目中放置拖放功能,但我没有遇到过这个问题,但我很好奇并且真的想看看我是否能想出一个比你链接的页面中描述的方法更好的方法至.我希望我能清楚地理解你想要做的一切,总的来说,我认为我成功地以更加优雅和简单的方式解决了这个问题.
简而言之,对于这样的问题,如果你提供一些代码就会很棒,这样我们就可以确切地看到你正在尝试做什么.我这样说只是因为我在我的解决方案中假设了一些关于你的代码的东西...所以希望它非常接近.
这是代码,我将在下面解释:
this.LabelDrag.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.LabelDrag_QueryContinueDrag); this.LabelDrag.MouseDown += new System.Windows.Forms.MouseEventHandler(this.LabelDrag_MouseDown); this.LabelDrag.MouseUp += new System.Windows.Forms.MouseEventHandler(this.LabelDrag_MouseUp); this.LabelDrop.DragDrop += new System.Windows.Forms.DragEventHandler(this.LabelDrop_DragDrop); this.LabelDrop.DragEnter += new System.Windows.Forms.DragEventHandler(this.LabelMain_DragEnter); public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void LabelDrop_DragDrop(object sender, DragEventArgs e) { LabelDrop.Text = e.Data.GetData(DataFormats.Text).ToString(); } private void LabelMain_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.Text)) e.Effect = DragDropEffects.Copy; else e.Effect = DragDropEffects.None; } private void LabelDrag_MouseDown(object sender, MouseEventArgs e) { //EXTREMELY IMPORTANT - MUST CALL LabelDrag's DoDragDrop method!! //Calling the Form's DoDragDrop WILL NOT allow QueryContinueDrag to fire! ((Label)sender).DoDragDrop(TextMain.Text, DragDropEffects.Copy); } private void LabelDrag_MouseUp(object sender, MouseEventArgs e) { LabelDrop.Text = "LabelDrag_MouseUp"; } private void LabelDrag_QueryContinueDrag(object sender, QueryContinueDragEventArgs e) { //Get rect of LabelDrop Rectangle rect = new Rectangle(LabelDrop.Location, new Size(LabelDrop.Width, LabelDrop.Height)); //If the left mouse button is up and the mouse is not currently over LabelDrop if (Control.MouseButtons != MouseButtons.Left && !rect.Contains(PointToClient(Control.MousePosition))) { //Cancel the DragDrop Action e.Action = DragAction.Cancel; //Manually fire the MouseUp event LabelDrag_MouseUp(sender, new MouseEventArgs(Control.MouseButtons, 0, Control.MousePosition.X, Control.MousePosition.Y, 0)); } } }
我遗漏了大部分设计器代码,但包含了事件处理程序链接代码,因此您可以确定与什么相关联.在我的示例中,标签LabelDrag和LabelDrop之间发生拖放.
我的解决方案的主要部分是使用QueryContinueDrag事件.在该控件上调用DoDragDrop后,键盘或鼠标状态发生更改时,将触发此事件.您可能已经这样做了,但是调用作为源的控件的DoDragDrop方法而不是与表单关联的方法非常重要.否则QueryContinueDrag将不会触发!
需要注意的一点是,当您在放置控件上释放鼠标时,QueryContinueDrag实际上会触发,因此我们需要确保允许这样做.这是通过检查Mouse位置(使用全局Control.MousePosition属性检索)是否在LabelDrop控件矩形内部来处理的.您还必须确保使用PointToClient将MousePosition转换为相对于客户端窗口的点作为Control.MousePosition返回屏幕相对位置.
因此,通过检查鼠标不超过下拉控制和鼠标按钮现在了我们已经有效地捕捉到了LabelDrag控制MouseUp事件!:)现在,您可以在此处执行您想要执行的任何处理,但如果您已经在MouseUp事件处理程序中使用了代码,则效率不高.因此,只需从此处调用MouseUp事件,向其传递必要的参数,MouseUp处理程序将永远不会知道其中的差异.
只是注意,虽然,我称之为的DoDragDrop从内部在我的例子MouseDown事件处理程序,此代码应从未真正得到一个直接的MouseUp事件触发.我只是把那些代码放在那里,以表明可以做到这一点.
希望有所帮助!