Re-sizing and Re-positioning - Part 1
Download the demo code (Visual Studio.Net Project)
Part 1 | Part 2
Introduction
This article describes two custom written classes that let you add selection handles to your application. The handles are drawn via the .NET framework graphics classes and respond to mouse actions such as dragging and hovering. They allow you to dynamically re-size and re-position the object under control. Here is a screenshot of the demo application in action.
Figure 1: Screenshot of object under selection
Selection Handles are very common at design time - we use them often within the IDE when developing GUI based applications. Drop a button from the toolbox onto a form and it will be "selected", indicated by a border drawn around the object, and handles are available to re-size the object. The object itself can also be clicked on and dragged around.
If you want this functionality in your own application at runtime then it is quite easy to implement. However you may struggle to find examples on the net, apart from some commercial (ie. costing you money) solutions. Here is an example of how you can do it yourself. This example is limited to rectangular objects, is presented in VB.NET, and is free!
Architecture
There are two classes:
- SeqHandle
- SeqHandleManager
SeqHandle represents an individual square widget - 8 of these will get drawn around a selected object. The purpose of the second class, SeqHandleManager, is to be aware of the dimensions of the rectangular object being selected, to draw the widgets, and to process all mouse activity related to both the selection itself, and to the handles, such as hovering over, dragging to re-size, and dragging to re-position.
Within your application, it is a simple matter of hooking into the following mouse events for the relevant object(*). This might be a Form, or a UserControl for example.
- MouseDown
- MouseMove
- MouseUp
Through the mouse events you control whether the selection handles and border are displayed, and track co-ordinate changes as a mouse drag occurs. You also control the cursor selection so that the appropriate cursor is displayed.
And you also hook into the Paint event. Through the Paint event you handle the actual drawing. The PaintEventArgs gives you a Graphics object which the HandleManager uses to draw the selection border and the handles.
(*) This can become complicated in circumstances where the object you want to select is a Panel or other object that receives its own mouse evnets. When the mouse is moving over the Form, the Forms events are triggered, but when the mouse starts moving over the Panel on the Form, the Panel's mouse events are triggered and these do not bubble up to raise the Parent Form's mouse events. In this circumstance you need to add mouse events for both Form and Panel and process appropriately, and be aware that the X,Y co-ordinates of mouse events over the Panel will be relative to its Origin, not the Forms. See the demo project for more information, as it contains some commented out code for dealing with this situation.
The demo itself draws a rectangle onto the form and this is the object that is the focus of the selection. This is easier to process as the rectangle is not added to the Form's Controls collection and won't intercept mouse events.
Part 1 | Part 2