Which event on a Control level is equivalent to Form.Load event? - vb.net

I am trying to create multiple custom controls in my application, For example:
Public Class CbsDataGridView
Inherits DataGridView
'...
Private Sub CbsDataGridView_Enter(sender As Object, e As EventArgs) Handles MyBase.Enter
'Code here omitted, not related to the question.
LoadGrid()
End Sub
Private Sub LoadGrid()
'Code here omitted, not related to the question.
End Sub
'...
End Class
Public Class CbsDateTimePicker
Inherits DateTimePicker
Private Sub CbsDateTimePicker_Enter(sender As Object, e As EventArgs) Handles MyBase.Enter
'Code here omitted, not related to the question.
End Sub
End Class
When adding these controls to a new empty form. Here's the two scenarios I've faced:
Scenario 1:
- Drag And Drop CbsDateTimePicker into the form
- Drag And Drop CbsDataGridView into the form
- Run Application - Load The New Form
- CbsDateTimePicker_Enter event fires.
- CbsDataGridView_Enter event doesn't fire.
Scenario 2:
- Drag And Drop CbsDataGridView into the form
- Drag And Drop CbsDateTimePicker into the form
- Run Application - Load The New Form
- CbsDataGridView_Enter event fires.
- CbsDateTimePicker_Enter event doesn't fire.
I think I miss-understood the Enter event of Controls.
What I am looking for is an event that acts like the Form.Load event which will fire when the form containing the control loads.
Is there a direct way to implement this functionality? Or should I be looking for another way?

Enter event will fire whenever the control activates by using mouse or keyboard. Also whenever you set the active control of the form by code, the event will fire.
Controls don't have a Load event similar to Load event of the Form, but they have a virtual OnCreateControl which is called when the control is first created. You can override it and add custom logic to that method, or even raise a custom Load event for your control.

Related

Windows form actions like close through custom user control code?

I have made a title bar (custom user control) that contains five controls. They are all labels but each one do different "job".
For example, one of them is an exit form button. If I put a click event into my custom user control's code, for example...
Private Sub ExitButton_Click(sender As Object, e As EventArgs) Handles ExitButton.Click
Close()
End Sub
I get this error...
BC30451 'Close' is not declared. It may be inaccessible due to its protection level.
On the other hand I can't put it into my project's code cause it can't find ExitButton as "isolated" control and do close().
Any suggestions? I also want to do the same thing with minimize, maximize etc.
Let me guess; your button is in the user control. You try to call Close() on the UserControl class, which obviously is not a window and does not have it.
There are three solutions:
Use the ParentForm property and call Close() on it (e.g. ParentForm.Close()). Easy but not too flexible; if you want to do other things than those which are implemented in the Form base class (like Close()), e.g. specific to the main form, you would have to cast it first and check if it's really the form you thought of. Also, all those things would need to be exposed with Public or Internal, don't expose what you don't have to expose.
You pass the Form to the UserControl. Horrible because passing stuff around just ends up in spaghetti code.
Better, raise an event by the UserControl which you handle in the form the UserControl is on. That's probably the most flexible approach.
Here's a small code example solving this with an event:
Open the code of the UserControl and add an event signature and raise that event when you click the button:
Public Class MyUserControl
Public Event ButtonClicked(sender As Object, e As EventArgs)
Private Sub MyButton_Click(sender As Object, e As EventArgs) Handles MyButton.Click
RaiseEvent ButtonClicked(sender, e)
End Sub
End Class
Then, in your Form, attach to the ButtonClicked event of the UserControl:
Public Class MyForm
Private Sub MyUserControl1_ButtonClicked(sender As Object, e As EventArgs) Handles MyUserControl1.ButtonClicked
Close()
End Sub
End Class
If you re-use the event for multiple buttons, you can check which button it is through the sender passed to the event. (Of course this can be optimized by just passing a casted Button instance as the event parameter, this is just a simple example).
Where did you get "close" from? You exit an application with application.exit()
If you want to close Application you can use:
Application.Exit()
If you want to close Form:
Me.Close()
To close the form you use me.
me.close

User Control Event against Form Control Event

Here is my situation, I have a user control that have the Leave event:
Private Sub MyControl_Leave(sender As Object, e As EventArgs) Handles Me.Leave
If Me.Enabled Then
MsgBox(Property1)
End If
End Sub
I have this to prevent Leave Event from triggering when the control is Disabled.
Then on my form, the control also has its own Leave event because I need to set some Properties that the Leave Event on the User Control needs.
Private Sub myControlOnForm_Leave(sender As Object, e As EventArgs) Handles MyControlOnForm.Leave
MyControlOnForm.Property1 = "value1"
End Sub
What happens is the first event that triggers is the one on the User Control and then the one on the form.
Now my problem is, as the code states above, I need the Form Event to trigger first before the User Control Event.
Is there any work around for this?
The form needs to call a procedure in the user control after it's finished handling the event. Just remove the Handles Me.leave statement, and the private statement. use the sub from your form to call the controls sub which was intended to handle the event.
Note that I've changed sender As object to sender As Mycontrol.
Sub MyControl_Leave(sender As Mycontrol, e As EventArgs)
If Me.Enabled Then
MsgBox(Property1)
End If
End Sub
Code on form
Private Sub myControlOnForm_Leave(sender As Mycontrol, e As EventArgs) Handles MyControlOnForm.Leave
MyControlOnForm.Property1 = "value1"
sender.MyControl_Leave(sender, e)
End Sub
What happens is the first event that triggers is the one on the User Control and then the one on the form.
Now my problem is, as the code states above, I need the Form Event to
trigger first before the User Control Event.
First off, you are using the incorrect term in that problem statement. It is not an event triggering order issue, but rather an issue in order in which the event handlers registered for the UserControl's Leave event execute.
.Net events are a form of syntactic sugar for the invocation of a multicast delegate. When an event is raised a delegate is invoked and the order in which the handlers are executed is the order in which they were added to the delegate. You can gain an understanding of this by working through the various "Walkthrough" tutorials located under Events (Visual Basic).
The Leave event is Raised by calling the Overridable OnLeave method inherited from the Control Class that is in the inheritance tree of the UserControl Class. It is considered bad form for a class to handle its own generated event; the preferred method is Override the method that raise the event.
In your case, you want the form that subscribes to the event to be notified first so that it can modify a property on the UserControl before some it performs some action in response to Leaving the UserControl.
Public Class UserControl1
Protected Overrides Sub OnLeave(e As EventArgs)
MyBase.OnLeave(e) ' this calls the base method that Raises the event
' all event handlers will run before the subsequent code
' executes
If Me.Enabled Then
'do something
End If
End Sub
End Class

How to check a checkbox of form 1 from another form in vb.net?

I have two forms, form 1 and form 2 (windows application). How can i access and check a checkbox in form 1 from form 2. Initially i tried calling the form name and then the control like form1.chkCanada.checked = true, it did not work. And then i added a property in form 1
Public Property abc As Boolean
Get
Return chkCanadianStmtInd.Checked
End Get
Set(value As Boolean)
chkCanadianStmtInd.Checked = value
End Set
End Property
and then in form 2
Dim frm As New frm1
frm.abc = True 'Checked
And it still doesnt work. Am i missing anything here?
Alternatively you can pass a handle of form1 to form2 constructor
Form1:
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim _form2 As New Form2(Me)
_form2.Show()
End Sub
End Class
Form2:
Public Class Form2
Public Sub New(ByVal _form1 As Form1)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_form1.CheckBox1.Checked = True
End Sub
End Class
Consolidating comments here:
In order to access controls on a form that shows another form to the user you have two options, if no interaction is needed with the first form while the second form is active you can use showdialog and do all of your logic after the second form has closed, if you ned to maintain the ability to interact with the first form while the second is still open then you need to use custom events.
Showdialog:
The simpler of the two options is to switch your form.show() function calls to form.showdialog(). This effectively tells the first form that it should stop processing at the form.showdialog() line and wait for the child form to close before proceeding. Once the second form is closed the first form will pick up where it left off and that would be where any processing that relies on the values of the second form would take place.
Custom Events:
If you want to allow the user to interact with both the first and second forms at the same time then you will need to use custom events. In order to do this you will need three things. The custom event, a raiseevent call and an event handler.
So in your Form2 class you will need to declare the custom event. In this case since you are trying to check(or uncheck I assume) a box your custom event declaration will look like:
public event ChangeCheckedValue(byref state as boolean)
Now on your button click event you will need to raise the event to the handler on Form1:
RaiseEvent ChangeCheckedValue(booleanValue)
Now that those statements are in place you will need to changed your form2 object that is being shown by Form1. What I normally do is make Form2 a form wide variable on Form1 and declare it like:
private withevents frm as Form2
Once you have the frm variable in your Form1 class you can add a handler for the ChangeCheckedValue event:
protected sub HandleCheckChanged(byref bln as boolean) handles frm.ChangeCheckedValue
'Set the checked state of your checkbox.
End sub
Once you have all that set up you should see what you expect.

vb.net winforms how raise a custom event to a different control

I have a made a custom datagridview with custom column objects. One of the columns in an edit button column which has a text box and a button to the right of it. This is a user control. What I am having problems with is when the user presses the button on the control I want an event to be raised on the datagridview which contains this column. I am doing this in winforms and vb.net. If anyone knows how to raise an event from the user control column which has the button to the datagridview which contains the column then it would be greatly appreciated.
Thanks
In your custom control, simply declare an event that the control will raise:
Public Class MyUserControl
Public Event MyEvent as EventHandler
...
'Somewhere in you user control code, you want to raise the event
RaiseEvent MyEvent(Me, EventArgs.Empty) 'using empty args for demo purposes
End Class
Then, in your form, you simply declare an event handler as usual:
Private Sub MyUserControl_MyEvent(sender as Object, e as EventArgs) Handles MyUserControl.MyEvent
... 'Whatever you need to do in reaction to the event
End Sub
Hope this helps

VB.Net WinForms UserControl

I have two UserControls already loaded how to change TextBox text property on a UserControl from the other loaded one.
Lets say your user controls are named UserControl1 and UserControl2. Unless UserControl1 has a reference to UserControl2 it can't directly make changes to it. In that situation the one solution is to allow the form or parent control to handle making the change, by adding an event to UserControl1 and handling it on the form.
In UserControl1:
'Define an Event the form can handle at the class level
Public Event SomePropertyUpdated()
Then in whatever method you need it to be in, when you would want to change the textbox on the other control raise your event:
RaiseEvent SomePropertyUpdated()
In the form:
'The sub that is called when the second control needs updated
Public Sub UpdateTextBoxes()
UserControl2.Textbox1.text = userControl1.Property
End Sub
In the load event of the form Add the handler for your created event:
AddHandler UserControl1.SomePropertyUpdated, AddressOf UpdateTextBoxes
In the closed Event of the form remove the handler for the event:
RemoveHandler UserControl1.SomePropertyUpdated, AddressOf UpdateTextBoxes
That is one of a few ways to handle the situation. The specifics of what you are trying to do usually dictates what method to use.