[RESOLVED] Prevent developer from placing a UserControl more than one time in Design Time
I am working on a UserControl and I am looking for a way to prevent developer to place this UserControl more than one time into a form, in Design Time. In other words, how can I detect if my UserControl is already placed into ParentForm or not, in Design Time and prevent the second placement if there is already one there?
I tried something like this example below... First I am not sure if this is the "correct" way and second, I can't find how to remove or stop the placement of UserControl in case there is already one.
Again, all this, in Design Time!!!
vb.net Code:
Private Sub MyUserControl_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim _Count As Integer
Dim _UserControl As MyUserControl
For Each _UserControl In Me.ParentForm.Controls
If _UserControl.Name.Contains("MyUserControl") Then
_Count += 1
End If
Next
If _Count > 1 Then
MsgBox("Control have been placed.")
Else
MsgBox("Control haven't placed yet.")
End If
End Sub
Re: Prevent developer from placing a UserControl more than one time in Design Time
Try this:
VB.Net Code:
Private Sub Me_ParentChanged(sender As Object, e As EventArgs) Handles Me.ParentChanged
Dim f = DirectCast(Me.FindForm, Control)
If f IsNot Nothing Then
'check to see if we are the only one on the form
Dim c = f
Do Until c Is Nothing
If TypeOf c Is UserControl1 AndAlso c IsNot Me Then
Throw New NotSupportedException("You cannot have more than one of these controls on your form at a time")
End If
c = f.GetNextControl(c, True)
Loop
End If
End Sub
Change UserControl1 to the name of your control...
The above will work ... but...
... You may want to show a message box before you throw the exception for an easier to understand message...
... I don't know of a way to cancel the control creation and only show a nice handled error though...
If you show your own message you can also choose to set Me.Parent = Nothing instead of throwing the exception to not insert the control ... but it also shows another error after stating: "'child' is not a child control of this parent"
Kris
Re: Prevent developer from placing a UserControl more than one time in Design Time
Thank you very much my friend for your answer, it worked!!! Here is how I used your example with some changes...
vb.net Code:
Private Sub Me_ParentChanged(sender As Object, e As EventArgs) Handles Me.ParentChanged
If Me.DesignMode AndAlso Me.ParentForm IsNot Nothing Then
Dim _UserControl = DirectCast(Me.ParentForm, Control)
If _UserControl IsNot Nothing Then
Do Until _UserControl Is Nothing
If TypeOf _UserControl Is MyUserControl AndAlso _UserControl IsNot Me Then
Throw New ArgumentOutOfRangeException("", "You can place only one " & _UserControl.Name & " control per form.")
End If
_UserControl = _UserControl.GetNextControl(_UserControl, True)
Loop
End If
End If
End Sub
One more question...
vb.net Code:
Private Sub Me_ParentChanged(sender As Object, e As EventArgs) Handles Me.ParentChanged
'Blah blah blah...
End Sub
and
vb.net Code:
Protected Overrides Sub OnParentChanged(e As EventArgs)[INDENT]MyBase.OnParentChanged(e)
'Blah blah blah...
End Sub
is the same thing?
Re: Prevent developer from placing a UserControl more than one time in Design Time
Quote:
I don't know of a way to cancel the control creation
Haven't got an ide in front of me to check but you could presumably just remove it:-
Code:
f.Controls.Remove(Me)
By the way, I think there's a typo in your code:-
Should be:-
Code:
Dim c = f.GetNextControl(c, True)
Unless you actually want to check the control isn't the form for some reason
edit> crossed over
You may or may not want this:-
While that's in they could add a second control to the form at run time.
Quote:
is the same thing?
Not quite. The "On" methods fire the events and are the intended method for firing the event from code, rather than calling the handling event directly. The correct way to wire up an event handler is the first one.
Re: Prevent developer from placing a UserControl more than one time in Design Time
Quote:
Originally Posted by
FunkyDexter
You may or may not want this:-
While that's in they could add a second control to the form at run time.
Do you mean if developer try to add this control programmatically?
Re: Prevent developer from placing a UserControl more than one time in Design Time
Quote:
Originally Posted by
FunkyDexter
You may or may not want this...
So I ended up on this...
vb.net Code:
Private Sub Me_ParentChanged(sender As Object, e As EventArgs) Handles Me.ParentChanged
If Me.ParentForm IsNot Nothing Then
Dim _UserControl = DirectCast(Me.ParentForm, Control)
If _UserControl IsNot Nothing Then
Do Until _UserControl Is Nothing
If TypeOf _UserControl Is CmosTitleBar AndAlso _UserControl IsNot Me Then
Throw New ArgumentOutOfRangeException("", "You can place only one " & _UserControl.Name & " control per form.")
End If
_UserControl = _UserControl.GetNextControl(_UserControl, True)
Loop
End If
End If
End Sub
Re: Prevent developer from placing a UserControl more than one time in Design Time
Quote:
Originally Posted by
Simonetos The Greek
So I ended up on this...
Code:
Private Sub Me_ParentChanged(sender As Object, e As EventArgs) Handles Me.ParentChanged
If Me.ParentForm IsNot Nothing Then
Dim _UserControl = DirectCast(Me.ParentForm, Control)
If _UserControl IsNot Nothing Then
Do Until _UserControl Is Nothing
If TypeOf _UserControl Is CmosTitleBar AndAlso _UserControl IsNot Me Then
Throw New ArgumentOutOfRangeException("", "You can place only one " & _UserControl.Name & " control per form.")
End If
_UserControl = _UserControl.GetNextControl(_UserControl, True)
Loop
End If
End If
End Sub
This is incorrect : _UserControl = _UserControl.GetNextControl(_UserControl, True)
... it will only go into controls... look @ my first example...
Re: Prevent developer from placing a UserControl more than one time in Design Time
Quote:
Originally Posted by
i00
This is incorrect : _UserControl = _UserControl.GetNextControl(_UserControl, True)
... it will only go into controls... look @ my first example...
Yes but I can't understand this part What is f and what is c? If f is the ParentForm and c the UserControl, then why c=f?
Re: [RESOLVED] Prevent developer from placing a UserControl more than one time in Des
Quote:
What is f and what is c? If f is the ParentForm and c the UserControl, then why c=f?
That confused me too but it's not necessarily wrong. It means that the first pass through the loop will check that the user control isn't the form and I can't think why you'd do that. But subsequent passes through the loop will check the controls because of this line within the loop: c = f.GetNextControl(c, True).
So at worst i00's code will do an extra pointless iteration but will still check the controls correctly. At best, he's thought of something I've missed and there's a good reason for checking against the form itself on that first pass.
Personally I think i00's solution is correct except that that one line should be Dim c = f.GetNextControl(c, True)
Re: [RESOLVED] Prevent developer from placing a UserControl more than one time in Des
Quote:
Originally Posted by
FunkyDexter
That confused me too but it's not necessarily wrong. It means that the first pass through the loop will check that the user control isn't the form and I can't think why you'd do that. But subsequent passes through the loop will check the controls because of this line within the loop: c = f.GetNextControl(c, True).
So at worst i00's code will do an extra pointless iteration but will still check the controls correctly. At best, he's thought of something I've missed and there's a good reason for checking against the form itself on that first pass.
Personally I think i00's solution is correct except that that one line should be Dim c = f.GetNextControl(c, True)
Let's see if he will give us a logical explanation like yours!!! :)
Re: [RESOLVED] Prevent developer from placing a UserControl more than one time in Des
Ah, just had a thought. GetNextControl gets the next control in tab order after the control passed in, in this case c. On the first pass c won't be anything. By setting it to the form he gives it a start point.
Personally, I would just chance the Do Until loop to a For Each loop. Again, I'm afraid I don't have an ide in front of me but it should be something like:-
vb.net Code:
For Each c as Control in f.controls
'check it's not your user control
Next
Re: [RESOLVED] Prevent developer from placing a UserControl more than one time in Des
Quote:
Originally Posted by
FunkyDexter
Ah, just had a thought. GetNextControl gets the next control
in tab order after the control passed in, in this case c. On the first pass c won't be anything. By setting it to the form he gives it a start point.
Personally, I would just chance the Do Until loop to a For Each loop. Again, I'm afraid I don't have an ide in front of me but it should be something like:-
vb.net Code:
For Each c as Control in f.controls
'check it's not your user control
Next
I think you are right my friend!!! I tried this and works 100%...
vb.net Code:
Dim _ParentForm = DirectCast(Me.FindForm, Control)
If _ParentForm IsNot Nothing Then
For Each _Control As Control In _ParentForm.Controls
If TypeOf _Control Is MyUserControl AndAlso _Control IsNot Me Then
Throw New ArgumentOutOfRangeException("", "You can place only one " & _Control.Name & " control per form.")
End If
_Control = _ParentForm.GetNextControl(_Control, True)
Next
End If