问题
I am using vb.net winforms to create an application which contains a user control, I am also authoring the user control.
The user control is named activate1
The form containing the usercontrol (and other content) is named form1
currently I am trying to enable a button on form1 when a maskedtextbox on activate1 is completed
I attempted to do this by:
Private Sub MaskedTextBox1_TextChanged(sender As Object, e As EventArgs) Handles MaskedTextBox1.TextChanged
If MaskedTextBox1.Text.Count = 34 Then
Form1.SimpleButton1.Enabled = True
Else
Form1.SimpleButton1.Enabled = False
End If
End Sub
however I receive an error when running the application "The form referred to itself during construction from a default instance, which led to infinite recursion" so instead I tried
Private Sub MaskedTextBox1_TextChanged(sender As Object, e As EventArgs) Handles MaskedTextBox1.TextChanged
If MaskedTextBox1.Text.Count = 34 Then
me.SimpleButton1.Enabled = True
Else
me.SimpleButton1.Enabled = False
End If
End Sub
however this flags and does not allow compiling as I am referring to a button that does not exist in the user control
How can I accomplish this
回答1:
The reason for the 1st error is that you use the type name to refer to Form1 where you'd need the concrete instance of the parent form. You can access the parent form by accessing the ParentForm-property:
Private Sub MaskedTextBox1_TextChanged(sender As Object, e As EventArgs) Handles MaskedTextBox1.TextChanged
Dim form = TryCast(ParentForm, Form1)
If form IsNot Nothing Then
If MaskedTextBox1.Text.Count = 34 Then
form.SimpleButton1.Enabled = True
Else
form.SimpleButton1.Enabled = False
End If
End If
End Sub
Please note that this approach couples your Form and your UserControl tightly. Though it will work, it reduces the reusability of your UserControl (in fact, you can only use it on Form1 and not on other forms). Though you can improve this, e.g. by creating an interface, but the UserControl will always by tied to the forms that support this button in one way or the other.
A more reusable approach would be to raise an event in your UserControl and handle this in the parent form, e.g.:
Public Class ActivationInfoEventArgs
Inherits EventArgs
Public Property Completed As Boolean
End Class
Public Event ActivationInfoChanged As EventHandler(Of ActivationInfoEventArgs)
Private Sub MaskedTextBox1_TextChanged(sender As Object, e As EventArgs) Handles MaskedTextBox1.TextChanged
Dim completed As Boolean
If MaskedTextBox1.Text.Count = 34 Then
completed = True
Else
completed = False
End If
RaiseEvent ActivationInfoChanged(Me, New ActivationInfoEventArgs() With { .Completed = completed })
End Sub
You add a handler for the event in Form1 and (de-) activate the button in this handler. This way, you can use the UserControl on a wider variety of Forms.
来源:https://stackoverflow.com/questions/21660301/user-control-controling-containing-form