Database Search Solution
(New Version) Search Control
Free ASP.NET Controls
ASP.NET Media Player Control
Flash Video Player Control
ASP.NET Telecommute Jobs
Free IP Location Lookup
Test .Net Regular Expressions
CSS/Table/DIV Page Layouts
Article Sites Master List
.NET Windows Forms
General .NET Framework
Accepting Credit Cards
Runtime Control Sizing and Dragging Class
This article extends the Simple Runtime Control Sizing and Dragging Class by Jim Korovessis, as explained in his article at Code Project. The PickBox class provides sizing handles that allow the positioning and sizing on simple controls on a containing form.
Jim used C# to implement this class; however, I am using a VB.Net version of that class in my implementation. You can download sample VB.NET project, used in this tutorial.
The major functionality that I have written is identifying Panels and GroupBoxes as Containers and adding/removing controls to them by dragging in/out controls.
The ControlPickBox class exposes a "WireControl" method that attaches events to a passed control, implementing "pickbox" behavior. A control that is wired, when clicked, displays sizing handles around its edges enabling sizing and dragging of the control. This class is limited to allow dragging and resizing of one control at a time.
To use this class, one needs to only create an object of the class and call WireControl method for the controls to wire.
CP As New
The code above wires all the controls on our form enabling us to resize and move them at run-time. One can use this technique to allow dynamic positioning of the controls as well as complete dynamic layout design of the form.
The "WireControl" method attaches a Click event handler to each passed control. When called the event handler then attaches the "pickbox", made up of eight Label controls that act as sizing handles, to the clicked control. In addition, mouse event handlers are attached to the control allowing for dragging of the control on its parent form. In order to use the class allowing panels and group-boxes, Jim's functionality needed a slight bit of adjustment.
AddHandler m_control.Parent.Click, AddressOf Me.Parent_Click
AddHandler m_control.FindForm.Click, AddressOf Me.Parent_Click
The reason for this is that a controls Parent can be a Panel or a GroupBox. The Parent_Click method clears selection - i.e. when the user clicks the form, we clears any sizing handles around a selected control, and this we don't want to do when clicking a GroupBox or a Panel parent of a control, in which case we just want to shift the sizing handles to the new control pressed.
Let us now get down to identifying the parent control and adding out selected control to that control when dragged into it.
sender As Object,
ByVal e As
Ctl_MouseUp method is executed when the mouse button is released, i.e. the control is released. At this point we set our control at the new position, so this is the place that we need to identify our Parent and add the control accordingly.
When checking if a control is over another control, we use a loop on the Controls collection and check if a control comes on top of another. If so, then we add it to that control, and then again recall the method checking for the controls inside that container control. In other words, when a control is dragged, it can end up inside a panel, or inside a panel that is inside another panel that may be inside a group-box.
searchIn As Object)
The code above searches through the control collection for Panels and GroupBoxes and checks if the control is dropped onto either of them. If so, then it adds the control to that container, and recalls the same method for that container. Otherwise it exits the method.
In the sample attached with this project, you'll see a GroupBox and a Panel object on the form. Drag the group-box into the Panel, which'll move inside the panel, and then drag-in a text-box and drop it over the group-box. The application will add that text-box into the Group-Box successfully.
Now for the next part; to bring out the control from its container. When the user selects the control, we don't want it to be just moveable inside the container, but also be drag-able outside the container. To do this we need to remove the control from the container and add it to the form.
To accomplish this, I have modified the MouseDown event handler;
sender As Object,
ByVal e As
As you can see, when the mouse button is pressed I am checking if the parent of the control is not a Form. If it isn't, I get a new location for the control, remove it from the container, and add it to the form.
Why do we need to get a new location? Because the location property is defined according to the container. Suppose a button is located at X=5 and Y = 10 in a Panel Control. If we were to move it to the form, then the location would need to be justified according to the form which would be X=5 + Panel.X and Y = 10 + Panel.Y.
That is simple for a single container, but since we are allowing container within container, we need to be cautious about it.
The method above calculates the new location for our control. What it does is;
That's all there is to it. Try out the sample application attached with this tutorial. You can reach me at firstname.lastname@example.org. Feel free to send me questions or feedback. I would like to express a special thanks to Jim Korovessis for his wonderful class that made this article possible.
comments powered by Disqus