I'm calling a form from my main function, this form has a button on it; this form is defined inside its own class. My goal is that every time I click that button, the program will perform a task defined in the "click" event, but it will also perform a task in the main function at the moment of clicking that button.
I tried switching between oForm.Show(), but the main function runs the code before even starting the form. I also used oForm.Show(vbModeless), but this causes the opposite: the code in the main function runs after the form was closed.
This is my code:
Imports System.Windows.Forms
Public Sub Main()
Dim oForm As New WinForm()
oForm.Show(vbModeless)
' I want to show this when I click the button
MsgBox("TASK 2")
End Sub
Public Class WinForm
Inherits System.Windows.Forms.Form
Public Sub New()
oForm = Me
With oForm
.FormBorderStyle = FormBorderStyle.FixedToolWindow
.StartPosition = FormStartPosition.CenterScreen
.Width = 300
.Height = 400
.Text = "MYFORM"
.ShowInTaskbar = False
End With
Dim oButton1 As New Button()
With oButton1
.Text = "CLICK ME!"
.Top = oForm.Bottom - 80
.Left = (oForm.Width/2) - oButton1.Width
.Enabled = True
.AutoSize = True
End With
Me.Controls.Add(oButton1)
AddHandler oButton1.Click, AddressOf oButton1_Click
End Sub
Public Sub oButton1_Click(ByVal oSender As System.Object, ByVal oEventArgs As System.EventArgs)
MsgBox("TASK 1")
End Sub
End Class
How can I achieve this?
Thanks in advance
Related
I have a series of controls: TextBox, Label and Panel. There controls are created dynamically in the code not the designer. My problem is that How can I call The Label and The Panel control using the .Name property that I set in the code?
This is what I have
Public Class frmMain
Private Sub DraControls()
Dim pans as New Panel
With pans
.AutoSize = True
.Parent = Me
.Name = "Panel1"
End With
Dim labs as New Label
With labs
.Text = "%"
.Name = "PercentageLabel00"
.Parent = pans
End With
End Sub
End Class
Then I have a click event that will make the label change its Text.
Dim PercentTextLabel As Label = CType(Me.Controls("PercentageLabel00"), Label)
PercentTextLabel.Text = "OK"
I need to change the text of the Label and I am getting an Error System.NullReferenceException: 'Object reference not set to an instance of an object.'
I already treid other approaches like Controls.Find but I got the same results
Thanks!
As per comments.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim p As Panel = CType(Me.Controls("Panel1"), Panel)
CType(p.Controls("PercentageLabel00"), Label).Text = "OK"
End Sub
Or in a single line
CType(CType(Me.Controls("Panel1"), Panel).Controls("PercentageLabel00"), Label).Text = "OK"
I created a class that inherits a timer class because I want to customize the Tick function, and I want to use this specific function in many classes without the need to change the function in all the timers every time.
Public Class FadeInTimer
Inherits Timer
Public Sub New()
MyBase.New()
Me.Enabled = False
Me.Interval = 75
End Sub
Private Sub FadeInTimer_Tick(sender As Object, e As EventArgs) Handles Me.Tick
Dim workingAreaWidth As Integer = Screen.PrimaryScreen.WorkingArea.Width - Me.Width
Me.Opacity += 0.1
If Not Me.Location.X <= workingAreaWidth Then
Me.Location = New Point(Me.Location.X - 30, Me.Location.Y)
End If
Me.Refresh()
If Me.Opacity = 1 Then
Me.Stop()
End If
End Sub
End Class
The purpose of this function is to make a simple fade in when the form is created. The problem is I can't use "Me." because I am in the Timer class, so, how can I make changes to the form from this class.
The first thing to do is to pass an instance of the form to be faded in inside the constructor of the custom timer, save that instance in a global class variable and add the tick handler with AddHandler like so
Public Class FadeInTimer
Inherits System.Windows.Forms.Timer
Dim parent As Form
Public Sub New(p As Form)
MyBase.New()
parent = p
AddHandler MyBase.Tick, AddressOf FadeInTimer_Tick
End Sub
Now, when you need to refer to the 'parent' form you use the parent variable and not the Me statement. Also, every time you need to refer to the timer, you should use MyBase statement
Private Sub FadeInTimer_Tick(sender As Object, e As EventArgs)
Dim workingAreaWidth As Integer = Screen.PrimaryScreen.WorkingArea.Width - Parent.Width
parent.Opacity += 0.1
If Not parent.Location.X <= workingAreaWidth Then
parent.Location = New Point(parent.Location.X - 30, parent.Location.Y)
End If
parent.Refresh()
If parent.Opacity = 1 Then
MyBase.Stop()
End If
End Sub
This could be tested in LinqPad using this code
Sub Main
Dim f As Form = New Form()
Dim t As FadeInTimer = New FadeInTimer(f)
f.Opacity = 0
t.Interval = 150
t.Start()
f.ShowDialog()
End Sub
I am trying lessen the line of code by creating a Public Sub calling in one line. However the form.MdiParent = Me generates error
frmParatemers is a Mdi Child form. frmMain is the MDI parent form.
From frmMain form
Dim MyCtrl As MenuClickOperations
MyCtrl.showChildDialog(New frmParameters)
This is my Class MenuClickOperations
Public Sub showChildDialog(ByVal form As Form)
Dim form2 As Form
For Each form2 In frmMain.MdiChildren
form2.Close()
Next
form.StartPosition = FormStartPosition.CenterScreen
form.MinimizeBox = False
form.MaximizeBox = False
form.MdiParent = Me
form.Show()
End Sub
Help me..Thanks
You should replace form.MdiParent = Me with form.MdiParent = formInstance. You can use frmMain, or the instance of frmMain (if different). If showChildDialog is called from frmMain, you can pass the frmMain instance as a parameter using Me in the call.
in frmMain
Dim MyCtrl As MenuClickOperations
MyCtrl.showChildDialog(New frmParameters, Me)
This is my Class MenuClickOperations
Public Sub showChildDialog(ByVal form As Form, ByVal Itself As Control)
Dim form2 As Form
For Each form2 In frmMain.MdiChildren
form2.Close()
Next
form.StartPosition = FormStartPosition.CenterScreen
form.MinimizeBox = False
form.MaximizeBox = False
form.MdiParent = Itself
form.Show()
End Sub
I am herewith develop an application but I have created a class which calls button events(i.e. enable or visible)
Public Class ClassfrmLoad
Dim btnAdd As New Button
Dim btnEdit As New Button
Private Sub FormLoad()
Me.btnAdd.Visible = True
Me.btnAdd.Enabled = True
Me.btnEdit.Visible = True
Me.btnEdit.Enabled = False
End Sub
End Class
I am actually created the button events class(classfrmLoad) for the way which buttons should be enabled and visible when each & every form loading.
There are 6 buttons in the forms (frm1, frm2 etc.,) like btnAdd, btnEdit, btnCancel etc., i don't want to display the buttons(visible/enable) while loading the form.
Here is the question:
How can i call this class(classfrmLoad) events to alter (enable/visible) the buttons positioned in the forms(frm1, frm2, etc.,) and how to get the buttons events in those forms?
Dear Sergio,
Thanks for your immediate response. I am missing something and it is not as expected, here is my complete code for the form including yours.
This is the code you suggested for the classfrmLoad:
Public Class ClassfrmLoad
Public Shared Sub FormLoad(ByRef Target As Form)
For Each ctl As Control In Target.Controls
If Not TypeOf ctl Is Button Then Continue For
Dim btn As Button = DirectCast(ctl, Button)
Select Case btn.Name.ToLower()
Case "btnadd"
btn.Visible = True
btn.Enabled = True
Case "btnsave"
btn.Visible = False
btn.Enabled = False
Case "btnedit"
btn.Visible = True
btn.Enabled = True
Case "btncancel"
btn.Visible = True
btn.Enabled = False
Case "btnclose"
btn.Visible = True
btn.Enabled = True
Case "btnupdate"
btn.Visible = False
btn.Enabled = False
Case "btnfind"
btn.Visible = False
btn.Enabled = False
'and so on
End Select
Next
End Sub
End Class
This is the code for the formload event:
Private Sub frmCreate_Unit_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ClassfrmLoad.FormLoad(Me)
'Display software and title of the page
Me.Text = msgCap & " | " & " CREATE UNIT"
Me.lblComp.Text = CompName
Me.stBar_User.Text = frmMain.stBar_User.Text
Me.stBar_UserID.Text = frmMain.stBar_UserID.Text
Me.stBar_G_ID.Text = frmMain.stBar_G_ID.Text
Me.stBar_G_No.Text = frmMain.stBar_G_No.Text
Me.cboUnit.Visible = False
Me.txtUnit_Long.Visible = True
Me.btnfind.Visible = False
Me.txtUnit_ID.Enabled = False
Me.btnadd.Focus()
End Sub
Please help me to sort out this one. Thanks...
Every form in WinForms is a class instance, inherited from Form class.
Because of this, you cannot make static references to it's members from another class, given any Form instance.
Generic class won't cut it either because you're after specific class members.
I would take advantage of the Controls collection and would check it's name and type. Once caught, we can cast the control to button and set it's visibility and access.
For this, you should make small adjustments to your code:
Public Class ClassfrmLoad
Public Shared Sub FormLoad(ByRef Target As Form)
For Each ctl As Control In Target.Controls
If Not TypeOf ctl Is Button Then Continue For
Dim btn As Button = DirectCast(ctl, Button)
Select Case btn.Name.ToLower()
Case "btnadd", "btnedit"
btn.Visible = True
btn.Enabled = True
'and so on
End Select
Next
End Sub
End Class
Changed the FormLoad visibility and access. It should be shared so we don't need to create unnecessary instances of this class
Added a parameter, passe by reference that referrs the target form. This will assure that you can use it on any class that inherits Form class
Iterated the Controls collection and find a candidate based on it's type and name
When found, we cast it to Button and access it's properties normally.
It's just an example, based on your code.
You should now call it on every Form's formload handler, like so:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ClassfrmLoad.FormLoad(Me)
End Sub
Finally I got the solution. It is very simple and any way thanks to sergio.
Here is the complete code.
Public Class ClassfrmLoad
Public Shared Sub formLoad(ByVal btnAdd As Button, ByVal btnEdit As Button, ByVal btnSave As Button, ByVal btnCancel As Button, ByVal btnClose As Button, ByVal btnUpdate As Button, ByVal btnFind As Button)
btnAdd.Visible = True
btnAdd.Enabled = True
btnSave.Visible = False
btnSave.Enabled = False
btnCancel.Visible = True
btnCancel.Enabled = False
btnClose.Visible = True
btnClose.Enabled = True
btnEdit.Visible = True
btnEdit.Enabled = True
btnUpdate.Visible = False
btnUpdate.Enabled = False
btnFind.Visible = False
btnFind.Enabled = False
End Sub
End Class
And calling proceedure in a form like this:
Dim x As New ClassfrmLoad
ClassfrmLoad.formLoad(Me.btnAdd, Me.btnEdit, Me.btnSave, Me.btnCancel, Me.btnClose, Me.btnUpdate, Me.btnFind)
I am developing a custom messagebox class like the following-
Public Class MyCustomMsgBox
Private MyForm As Form = New Form
Private lblHeadline As Label = New Label
Private lblMessageBody As Label = New Label
Private btnNo As Button = New Button
Private btnOk As Button = New Button
Private btnYes As Button = New Button
Public Sub New(ByVal Message As String)
With MyForm
.Width = 438
.Height = 214
.Controls.AddRange(New Control() {lblHeadline, lblMessageBody, btnNo, btnYes, btnOk})
End With
End Sub
Public Shared Function ShowErrorMsg(ByVal ErrorMessage As String) As Windows.Forms.DialogResult
Dim obj As MyCustomMsgBox = New MyCustomMsgBox(ErrorMessage)
obj.MyForm.ShowDialog()
End Sub
Public Shared function ShowSuccessMsg(ByVal SuccessMessage As String) As Windows.Forms.DialogResult
'some code
End Sub
Public Shared Function AskQuestions(ByVal Questions As String) As Windows.Forms.DialogResult
'some code
End Sub
Public Shared Function ShowExceptions(ByVal ExMessage As String) As Windows.Forms.DialogResult
'some code
End Sub
'Private Sub btnNo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNo.Click
' Windows.Forms.DialogResult.No()
'End Sub
End Class
Those functions are designed with related graphics, color, title and heading.
btnOk will return DialogResult.Ok, btnNo will return DialogResult.No and btnYes will return DialogResult.Yes
How do i return the dialog result with those functions?
How do i know that which button is pressed?
i dont know how to handle a button click event in a formless class.
Would you give me the idea?
Thank you in advance.
SKPaul
Start with the easy one. You will have to manually wire-up the events by using the AddHandler and RemoveHandler keywords this
AddHandler btnNo.Click, AddressOf btnNo_Click
btnNo is the button object. The ".Click" is the event you want captured. The AddressOf gets a pointer to the function (basically, it tells the compiler where the function is. Think of it as a different type of "handles".)
You'll have to remvoe the handler when your done, by doing this.
RemoveHandler btnNo.Click, AddressOf btnNo_Click
To set the Dialog Results, the form must be called via ShowDialog. You Simple set the DialogResults property of the form. I'd do it in the form.closing event.
me.DialogResult = Windows.Forms.DialogResult.OK
Me.DialogResult = Windows.Forms.DialogResult.Abort
Me.Close()
and it will return result Abort