最近要做车牌识别的,不同地区收费标准不一,所以想做个可以移动控件来给客户选择停车场收费条件的。
首先因为要自动排序控件选FlowLayoutPanel做容器,加若干Panel和FlowLayoutPanel。
以下教程需一定 C# 基础才能理解
引用文章有:
2.C#运行时鼠标移动控件 - 调用Windows API(ReleaseCapture)
3.http://www.it1352.com/19187.html (这个暂未引用)
按照引用1拖动控件时只有鼠标明显提示,但控件没有跟着鼠标走。
引用2的话只能拖动控件,不能拖到对应容器里面..
虽然2可以判断是否在别的容器上面以添加进去,但直接结合1的方法也行。
图为手稿
由于部分优化代码涉及商业内容,不予公示。
手稿图内左边为 flowLayoutPanel14,用于移动控件如果放进来就添加并自动排列
废话不多少,看代码
1 //调用系统Api 2 [DllImport("user32.dll", EntryPoint = "ReleaseCapture")] 3 public static extern void ReleaseCapture(); 4 [DllImport("user32.dll", EntryPoint = "SendMessage")] 5 public static extern void SendMessage(int hwnd, int wMsg, int wParam, int lParam); 6 7 //在程序启动时将要移动的控件设计时的左上角位置位置保存到 Tag ,这里面的容器都绑定了 8 private void MainForm_Load(object sender, EventArgs e) 9 { 10 panel67.Tag = panel67.Location; 11 flowLayoutPanel19.Tag = flowLayoutPanel19.Location; 12 flowLayoutPanel17.Tag = flowLayoutPanel17.Location; 13 panel68.Tag = panel68.Location; 14 panel53.Tag = panel53.Location; 15 } 16 //移动中的控件(DragDrop事件获取的控件部分为空) 17 Control contEven; 18 19 /// <summary> 20 /// 顶级容器 21 /// tabPage27 22 /// </summary> 23 private Control TopParent => tabPage27; 24 25 //作为可放置容器必须实现事件,多个绑定项 26 private void flowLayoutPanel14_DragEnter(object sender, DragEventArgs e) => e.Effect = DragDropEffects.Move; 27 28 //作为容器拖放完成时 29 private void FlowLayoutPanel14_DragDrop(object sender, DragEventArgs e) 30 { 31 //以下将需要移动的button控件放到目标位置,不同容器实现方法不同,这里以FlowLayoutPanel容器举例 32 FlowLayoutPanel flowPanel = sender as FlowLayoutPanel; 33 //移动控件于接收容器相同说明在同一容器内,忽略(因为绑定的相同事件,所以会触发到不应该获取的控件) 34 if (flowPanel == contEven) 35 return; 36 37 if (!flowPanel.Controls.Contains(contEven)) 38 { 39 flowPanel.Controls.Add(contEven); 40 flowPanel.Invalidate(); 41 } 42 } 43 44 //按住鼠标事件触发移动 45 //仅能作为容器移动,label无法调用系统api 46 private void TextBox81_MouseDown(object sender, MouseEventArgs e) 47 { 48 var panel = sender as Control; 49 contEven = panel; 50 51 //如果父容器不为最顶层容器 52 if (panel.Parent != TopParent) 53 { 54 //这里还有从容器里拿出来判断的代码未写,请自己思考 55 } 56 57 //置于顶层方便查看防止被挡 58 panel.BringToFront(); 59 60 #region 调用系统 Api 移动控件 61 ReleaseCapture(); 62 SendMessage((int)panel.Handle, 0xA1, 2, 0); 63 #endregion 64 //必须置于底层,否则无法移动到对应容器 65 panel.SendToBack(); 66 67 #region 松开鼠标时调用 DoDragDrop拖放 用于定位放在哪个容器内 68 panel.DoDragDrop(panel, DragDropEffects.All);//进入移动模式 69 #endregion 70 //拖放完成时,如果父容器是顶层容器则要返回原来的位置 71 if (panel.Parent == TopParent && panel.Tag != null) 72 { 73 panel.Location = (Point)panel.Tag; 74 } 75 }
还有诸多问题,比如容器移动的话必须点容器,点到容器里面的控件就移动不了。
况且这只是代码的部分,思路写出来而已。
来上演示
最后,其实由于公司原因,被刷掉了,老板要求安装别人的软件完全照抄,他说就不用思考。
看着他拿着别人六十多页的软件说明书叫我按着这个来做,我真是