|
Hi Ammar, please change "[" and "]" with "<" and ">". I wrote this way because the browser take my code as HTML when my post is shown. Now I know how to do it better
In the example:
private List[Control] _SelectedControls = new List[Control]();
after you change it:
private List<Control> _SelectedControls = new List<Control>();
Regards,
Diego
|
|
|
|
|
Thanks for a great piece of software. Would it be possible to change it so that a dragged control can be moved between containers, for example the label could be dropped into the panel or the panel into another panel?
|
|
|
|
|
thanks for your great work, but the problem is adding a Container control like a panel (level2) into a panel with another controls (level1), and then wiring the children controls of this panel. this way, when you click on a level1 control and then clicking on level2 control, you'll see that you have 2 controls selected.... !! got what i mean ?
ziad
|
|
|
|
|
hi,
1. how can i put the Mouse_Right Click event for selection of a control
while its now selecting on left mouse click i want to use Right mouse click for resize a control..
2. and how to put the control resize option under Tabs , pannel or subcontrols
MFS
|
|
|
|
|
how do i implement this class using keyboard to move controls..any idea guys???thanks...
|
|
|
|
|
Create a Keydown event under select Control method.
m_control.KeyDown += new KeyEventHandler(m_control_KeyDown);
and add this menthod .
private void m_control_KeyDown(object sender, KeyEventArgs e)
{
//left = 37,Up= 38,right= 39,down=40;
if (e.KeyValue == 37)
{
int l = m_control.Left - 1;
int t = m_control.Top;
int w = m_control.Width;
int h = m_control.Height;
l = (l < 0) ? 0 : ((l + w > m_control.Parent.ClientRectangle.Width) ?
m_control.Parent.ClientRectangle.Width - w : l);
t = (t < 0) ? 0 : ((t + h > m_control.Parent.ClientRectangle.Height) ?
m_control.Parent.ClientRectangle.Height - h : t);
m_control.Left = l;
m_control.Top = t;
MoveHandles();
}
if (e.KeyValue == 38)
{
int l = m_control.Left;
int t = m_control.Top - 1;
int w = m_control.Width;
int h = m_control.Height;
l = (l < 0) ? 0 : ((l + w > m_control.Parent.ClientRectangle.Width) ?
m_control.Parent.ClientRectangle.Width - w : l);
t = (t < 0) ? 0 : ((t + h > m_control.Parent.ClientRectangle.Height) ?
m_control.Parent.ClientRectangle.Height - h : t);
m_control.Left = l;
m_control.Top = t;
MoveHandles();
}
if (e.KeyValue == 39)
{
int l = m_control.Left + 1;
int t = m_control.Top;
int w = m_control.Width;
int h = m_control.Height;
l = (l < 0) ? 0 : ((l + w > m_control.Parent.ClientRectangle.Width) ?
m_control.Parent.ClientRectangle.Width - w : l);
t = (t < 0) ? 0 : ((t + h > m_control.Parent.ClientRectangle.Height) ?
m_control.Parent.ClientRectangle.Height - h : t);
m_control.Left = l;
m_control.Top = t;
MoveHandles();
}
if (e.KeyValue == 40)
{
int l = m_control.Left;
int t = m_control.Top + 1;
int w = m_control.Width;
int h = m_control.Height;
l = (l < 0) ? 0 : ((l + w > m_control.Parent.ClientRectangle.Width) ?
m_control.Parent.ClientRectangle.Width - w : l);
t = (t < 0) ? 0 : ((t + h > m_control.Parent.ClientRectangle.Height) ?
m_control.Parent.ClientRectangle.Height - h : t);
m_control.Left = l;
m_control.Top = t;
MoveHandles();
}
}
This should work fine.
I have used 1 px as a movement of the control when keyboard arrows are moved.
|
|
|
|
|
when i created a label at runtime through button click .....although they are also controls but cannot b selected........can anybody help me
|
|
|
|
|
Hello sir,
Thanks a lot,
i got exactly what i want..
Really a great article..
Thanks,
Irfan
"Take Care Not Chances"
|
|
|
|
|
how about impleminting a rotating of the control ? can it be done and how ?
Imagination is more important than knowledge...
{Albert Einstein}
|
|
|
|
|
This is exactly what i need too.....
i need to place the sizing handles at different rotation angles and add an extra sizing handle to rotate the control....if u hav any code for that then pls do help.
Thank you
|
|
|
|
|
i do have some , but i cant give it out since its in commercial product
Imagination is more important than knowledge...
{Albert Einstein}
|
|
|
|
|
This project does not run in visual studio 2005, it says it has problems during the conversion process, any help on this issue?
|
|
|
|
|
open the csproj file in a text editor and fill in the empty name="" attribute, then it will convert.
|
|
|
|
|
Hi,
I've been experimenting with this to try and get it to support custom made UserControls, but to no avail.
Are there any pointers you can give me?
|
|
|
|
|
Hi,
The sample code does not work for child controls inside panels etc.
Therefore, I have added the following recursive function which maps all controls in a form:
public void WireControls(Control _Control)
{
if (!(_Control is Form)) WireControl(_Control);
foreach (Control c in _Control.Controls)
{
WireControls(c);
}
}
Ronit
|
|
|
|
|
Anyone know the VC++ 2005 equivalent of Ronit's code?
I've managed to convert Jim Korovessis excellent Simple Runtime Control Sizing and Dragging Class over to VC++ but it doesn't work (builds and runs fine but doesn't show the sizing grab handles). It took me about half a day to complete the conversion.
I think it's because my controls are inside another control. So, I wanted to add Ronit's code to see if that's the case. But VC++ is complaining error C2275 when I changed:
if (!(_Control is Form))
to
if (_Control != Form)
It said 'System::Windows::Forms::Form' is illegal use of this type as an expression. Does anyone know? Thanks.
|
|
|
|
|
I don't take credit for all of this translation. The reasonably good conversion tool by Kamal Patel[^] did most of it, but I did the rest (and tested). Enjoy...
If anyone else has any additional tweaks to share, such as multi-select for block moving, deleting controls, etc, that would be lovely. I'm just now getting started with a new project and this code was EXACTLY what I was looking for! Thank you very much for sharing your expertise!
Public Class PickBox
'/ summary
'/ This class implements sizing and moving functions for
'/ runtime editing of graphic controls
'/ summary
'////////////////////////////////////////////////////////////////
' PRIVATE CONSTANTS AND VARIABLES
'////////////////////////////////////////////////////////////////
Private Const BOX_SIZE As Integer = 8
Private BOX_COLOR As Color = Color.White
Private m_container As ContainerControl
Private m_control As Control
Private lbl(8) As Label
Private startl As Integer
Private startt As Integer
Private startw As Integer
Private starth As Integer
Private startx As Integer
Private starty As Integer
Private dragging As Boolean
Private arrArrow() As Cursor = New Cursor() {Cursors.SizeNWSE, Cursors.SizeNS, _
Cursors.SizeNESW, Cursors.SizeWE, Cursors.SizeNWSE, Cursors.SizeNS, _
Cursors.SizeNESW, Cursors.SizeWE}
Private oldCursor As Cursor
Private Const MIN_SIZE As Integer = 20
'
' Constructor creates 8 sizing handles & wires mouse events
' to each that implement sizing functions
'
Public Sub New()
Dim i As Integer
For i = 0 To 8 - 1 Step i + 1
lbl(i) = New Label
lbl(i).TabIndex = i
lbl(i).FlatStyle = 0
lbl(i).BorderStyle = BorderStyle.FixedSingle
lbl(i).BackColor = BOX_COLOR
lbl(i).Cursor = arrArrow(i)
lbl(i).Text = ""
lbl(i).BringToFront()
AddHandler lbl(i).MouseDown, AddressOf Me.lbl_MouseDown
AddHandler lbl(i).MouseMove, AddressOf Me.lbl_MouseMove
AddHandler lbl(i).MouseUp, AddressOf Me.lbl_MouseUp
Next
End Sub
' ' PUBLIC METHODS
'
'
' Wires a Click event handler to the passed Control
' that attaches a pick box to the control when it is clicked
'
Public Sub WireControl(ByVal ctl As Control)
AddHandler ctl.Click, AddressOf SelectControl
End Sub
'///////////////////////////////////////////////////////////////
' PRIVATE METHODS
'///////////////////////////////////////////////////////////////
'
' Attaches a pick box to the sender Control
'
Private Sub SelectControl(ByVal sender As Object, ByVal e As EventArgs)
If TypeOf m_control Is Control Then
m_control.Cursor = oldCursor
'Remove event any pre-existing event handlers appended by this class
RemoveHandler m_control.MouseDown, AddressOf Me.ctl_MouseDown
RemoveHandler m_control.MouseMove, AddressOf Me.ctl_MouseMove
RemoveHandler m_control.MouseUp, AddressOf Me.ctl_MouseUp
m_control = Nothing
End If
m_control = CType(sender, Control)
'Add event handlers for moving the selected control around
AddHandler m_control.MouseDown, AddressOf Me.ctl_MouseDown
AddHandler m_control.MouseMove, AddressOf Me.ctl_MouseMove
AddHandler m_control.MouseUp, AddressOf Me.ctl_MouseUp
AddHandler m_control.Parent.Click, AddressOf Me.Parent_Click
'Add sizing handles to Control's container (Form or PictureBox)
Dim i As Integer
For i = 0 To 8 - 1 Step i + 1
m_control.Parent.Controls.Add(lbl(i))
lbl(i).BringToFront()
Next
'Position sizing handles around Control
MoveHandles()
'Display sizing handles
ShowHandles()
oldCursor = m_control.Cursor
m_control.Cursor = Cursors.SizeAll
End Sub
Public Sub Remove()
HideHandles()
m_control.Cursor = oldCursor
End Sub
Private Sub ShowHandles()
If Not m_control Is Nothing Then
Dim i As Integer
For i = 0 To 8 - 1 Step i + 1
lbl(i).Visible = True
Next
End If
End Sub
Private Sub HideHandles()
Dim i As Integer
For i = 0 To 8 - 1 Step i + 1
lbl(i).Visible = False
Next
End Sub
Private Sub MoveHandles()
Dim sX As Integer = m_control.Left - BOX_SIZE
Dim sY As Integer = m_control.Top - BOX_SIZE
Dim sW As Integer = m_control.Width + BOX_SIZE
Dim sH As Integer = m_control.Height + BOX_SIZE
Dim hB As Integer = BOX_SIZE / 2
Dim arrPosX = New Integer() {sX + hB, sX + sW / 2, sX + sW - hB, _
sX + sW - hB, sX + sW - hB, sX + sW / 2, sX + hB, sX + hB}
Dim arrPosY = New Integer() {sY + hB, sY + hB, sY + hB, sY + sH / 2, _
sY + sH - hB, sY + sH - hB, sY + sH - hB, sY + sH / 2}
Dim i As Integer
For i = 0 To 8 - 1 Step i + 1
lbl(i).SetBounds(arrPosX(i), arrPosY(i), BOX_SIZE, BOX_SIZE)
Next
End Sub
'///////////////////////////////////////////////////////////////
' MOUSE EVENTS THAT IMPLEMENT SIZING OF THE PICKED CONTROL
'///////////////////////////////////////////////////////////////
'
' Store control position and size when mouse button pushed over
' any sizing handle
'
Private Sub lbl_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
dragging = True
startl = m_control.Left
startt = m_control.Top
startw = m_control.Width
starth = m_control.Height
HideHandles()
End Sub
'
' Size the picked control in accordance with sizing handle being dragged
' 0 1 2
' 7 3
' 6 5 4
'
Private Sub lbl_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
Dim l As Integer = m_control.Left
Dim w As Integer = m_control.Width
Dim t As Integer = m_control.Top
Dim h As Integer = m_control.Height
If dragging Then
Select Case (CType(sender, Label)).TabIndex
Case 0
' Dragging top-left sizing box
If startl + e.X < startl + startw - MIN_SIZE Then
l = startl + e.X
Else
l = startl + startw - MIN_SIZE
End If
If startt + e.Y < startt + starth - MIN_SIZE Then
t = startt + e.Y
Else
t = startt + starth - MIN_SIZE
End If
w = startl + startw - m_control.Left
h = startt + starth - m_control.Top
Exit Select
Case 1
' Dragging top-center sizing box
If startt + e.Y < startt + starth - MIN_SIZE Then
t = startt + e.Y
Else
t = startt + starth - MIN_SIZE
End If
h = startt + starth - m_control.Top
Exit Select
Case 2
' Dragging top-right sizing box
If startw + e.X > MIN_SIZE Then
w = startw + e.X
Else
w = MIN_SIZE
End If
If startt + e.Y < startt + starth - MIN_SIZE Then
t = startt + e.Y
Else
t = startt + starth - MIN_SIZE
End If
h = startt + starth - m_control.Top
Exit Select
Case 3
' Dragging right-middle sizing box
If startw + e.X > MIN_SIZE Then
w = startw + e.X
Else
w = MIN_SIZE
End If
Exit Select
Case 4
' Dragging right-bottom sizing box
If startw + e.X > MIN_SIZE Then
w = startw + e.X
Else
w = MIN_SIZE
End If
If starth + e.Y > MIN_SIZE Then
h = starth + e.Y
Else
h = MIN_SIZE
End If
Exit Select
Case 5
' Dragging center-bottom sizing box
If starth + e.Y > MIN_SIZE Then
h = starth + e.Y
Else
h = MIN_SIZE
End If
Exit Select
Case 6
' Dragging left-bottom sizing box
If startl + e.X < startl + startw - MIN_SIZE Then
l = startl + e.X
Else
l = startl + startw - MIN_SIZE
End If
w = startl + startw - m_control.Left
If starth + e.Y > MIN_SIZE Then
h = starth + e.Y
Else
h = MIN_SIZE
End If
Exit Select
Case 7
' Dragging left-middle sizing box
If startl + e.X < startl + startw - MIN_SIZE Then
l = startl + e.X
Else
l = startl + startw - MIN_SIZE
End If
w = startl + startw - m_control.Left
Exit Select
End Select
If l < 0 Then
l = 0
Else
l = l
End If
If t < 0 Then
t = 0
Else
t = t
End If
m_control.SetBounds(l, t, w, h)
End If
End Sub
'
' Display sizing handles around picked control once sizing has completed
'
Private Sub lbl_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
dragging = False
MoveHandles()
ShowHandles()
End Sub
'///////////////////////////////////////////////////////////////
' MOUSE EVENTS THAT MOVE THE PICKED CONTROL AROUND THE FORM
'///////////////////////////////////////////////////////////////
'
' Get mouse pointer starting position on mouse down and hide sizing handles
'
Private Sub ctl_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
dragging = True
startx = e.X
starty = e.Y
HideHandles()
End Sub
'
' Reposition the dragged control
'
Private Sub ctl_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If dragging Then
Dim l As Integer = m_control.Left + e.X - startx
Dim t As Integer = m_control.Top + e.Y - starty
Dim w As Integer = m_control.Width
Dim h As Integer = m_control.Height
If l < 0 Then
l = 0
Else
If l + w > m_control.Parent.ClientRectangle.Width Then
l = m_control.Parent.ClientRectangle.Width - w
Else
l = l
End If
End If
If t < 0 Then
t = 0
Else
If t + h > m_control.Parent.ClientRectangle.Height Then
t = m_control.Parent.ClientRectangle.Height - h
Else
t = t
End If
End If
m_control.Left = l
m_control.Top = t
End If
End Sub
'
' Display sizing handles around picked control once dragging has completed
'
Private Sub ctl_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
dragging = False
MoveHandles()
ShowHandles()
End Sub
Private Sub Parent_Click(ByVal sender As Object, ByVal e As EventArgs)
Remove()
End Sub
End Class
Mark
|
|
|
|
|
Nice, I was also looking for this one,
how bout saving layout, how would you go about doing that? would you use xml?
para saaan naman ito
|
|
|
|
|
One feature that you could add would be the ability to double click on controls and change their text property.
For example, double click on a label (or GroupBox) and be able to type in the Text property directly in the form.
Whenever you have the time, of course Very nice piece of code that you have!
|
|
|
|
|
Just found out .NET won't let you resize your control in runtime. So how lucky was I to find this great class and add it to my project. Fantastic work!
To unwire or un-select at run-time simply add this event handler in the selectControl method:
m_control.Parent.Click +=new EventHandler(Parent_Click);
And then just add this event handler method where you call the Remove() method already supplied by the class.
private void Parent_Click(object sender, EventArgs e){ Remove(); }
Works!
Jamshed Rahman
|
|
|
|
|
i created the controls at runtime on panel using toolstrip in vs2005 using vb.net , so if add this it is working on the panel, toolstrip that' all . i am not able to access the runtime control like label1 ,checkbox1,RB1 ,TB1 like that . if i am able to access the control like label1 it is showing the squares but not able to resize the runtime controls ,
Urgent Help Needed ....
D.V.Sriram
|
|
|
|
|
Thank you for your post. This is exactly what I need. However, I tried it with a treeview and it didn't work. The control would not select, resize or move. I put another push button on the form and it worked fine. So, I am guessing that the code will only work for certain controls. If I am wrong or there is something I can change to make it work, please let me know. I need it to work with a treeview and a axWebBrowser control. Thank you.
|
|
|
|
|
Hi,
Firstly thanks to Jim for this great code, its exactly what I'm looking for. I tried this on a RichTextbox and I was having the same problem to fix it all i've done is a minor change to the WireControl
If ctl.GetType.ToString = "System.Windows.Forms.RichTextBox" Then
AddHandler ctl.GotFocus, AddressOf Me.SelectControl
Else
AddHandler ctl.Click, AddressOf Me.SelectControl
End If
and this seems to have done the trick.
PS I've converted the code in VB for my purposes.
|
|
|
|
|
Scratch that - noticed a few problems. I'll work away at it and I'll post if I get it sorted out
|
|
|
|
|
Hello! I was reading your article and found some things that can work slightly faster.
Why to not create event once and then to use repeatedly?
// No
lbl [i] .MouseDown + = <br />
new MouseEventHandler(this.lbl_MouseDown);<br />
// Yes
<br />
MouseEventHandler _onUp = new MouseEventHandler (this.lbl_MouseUp);<br />
for (int i = 0; i <8; i ++) {<br />
...<br />
lbl [i] .MouseDown + = _onDown;<br />
...<br />
}<br />
<br />
private void SelectControl(object sender, EventArgs e) <br />
{<br />
if (this.currMode == Mode.Default)<br />
return;<br />
if (m_control is Control) <br />
{<br />
...<br />
m_control.MouseDown -= onDown;
m_control.MouseMove -= onMove;
m_control.MouseUp -= onUp;
}<br />
m_control.MouseDown += onDown;<br />
m_control.MouseMove += onMove;<br />
m_control.MouseUp += onUp;<br />
...<br />
}<br />
private void lbl_MouseMove(object sender, MouseEventArgs e) {<br />
...<br />
if (dragging) {<br />
switch (((Label)sender).TabIndex) {<br />
case 0:
l = startl + e.X < startl + startw - MIN_SIZE ? startl + e.X : startl + startw - MIN_SIZE;<br />
...<br />
...<br />
}<br />
In your example it would be desirable to make two operating modes: Designer and Default.
These code allows two modes, but productivity of these code isn't fast.
<br />
public class Pickbox<br />
{<br />
public enum Mode {<br />
Default = 0,<br />
Designer<br />
}<br />
private Mode _currMode = Mode.Default;<br />
...<br />
public Mode CurrMode {<br />
get {<br />
return _currMode;<br />
}<br />
set {<br />
if(value == Mode.Designer) {<br />
}<br />
else {<br />
}<br />
}<br />
}<br />
}<br />
Probably, you know more suitable way
|
|
|
|
|