- Community Pick
Standard Three-Event Handling
Handle the mousedown, mouseup, mousemove events. You can set a "dragging now" flag in mousedown and record the initial mouse coordinates as the start point. In mousemove event, calculate the delta between the current mouse position and the start point. Set the window's new location using this delta as deviation value so the window will follow the mouse movement. Finally, set the "dragging now" flag to false to turn off the dragging.
It's a functional technique. But you need to handle three events and use flags and variables to accomplish the work.
Re-target Form-Dragging Events
A simpler way is to intercept the message loop of a form and re-target the mouse events hitting the client area and send them to the caption bar, as shown in the following code snippet:
If we have 20 forms and if we want them to have the similar behavior, using "copy & paste" to get the above sequence into each one of the 20 files would be nasty. A clean way is to create a derived class from Windows.Form:
and put the above codes in this class. Then you replace the default base class Form with InterceptProcForm for all your forms:
No more need to change your source codes -- all the forms are following your mouse now.
Handling User-Controls
The question now comes up: "What if a form is completely covered by a user control?" Now the message in WndProc() that originated from controls will be redirected to the control's caption which is meaningless to a control and the form will stay there quietly.
The solution is to handle the mousemove event and flood it to its owner form, as shown in this link: C# borderless form move by usercontrol.
Once again we need to take code reuse into consideration. In the above link, a generic type FormDragPanel is used and user panels can inherit from it to move the underlying form. It's an improvement but not enough. There are tens (if not tons) of various types of user control; for some of them we may want the dragging capability and for others we would just keep them as it is. A common type derived from UserControl is not feasible because C# does not support multiple inheritance. A quick thought is to create a separate FormDragXxxx for each type of control: FormDragLabel, FormDragPictureBox, FormDragProgressBar, etc. But your work does not end here. You need to touch the Designer-generated code and add an event chain in your form for each of the controls.
Inspired by Marcel, here's a kind of "adapter" pattern I've used to resolve the scenario. Simply add the following class FormDragBase in your project.
Derive your own form from this base class, then add the controls for which you want them to be transferable; for instance:
So... There you go. Simple and easy!
by: starlite551 on 2010-12-16 at 13:09:37ID: 22124
Select allOpen in new window