Sub To Summarize Click Events - vb.net

I have a windows form app where a user clicks a menu item to open a form. Once the menu item is clicked, it checks whether form is open and notifies user if form is open else it opens the form. The code for this is as below
Private Sub UsersBarButtonItem_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles UsersBarButtonItem.ItemClick
If Application.OpenForms().OfType(Of Users).Any Then
MessageBox.Show("Form Is Open", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
For Each openform In Application.OpenForms()
If TypeOf (openform) Is Users Then CType(openform, Users).BringToFront()
Next
Else
Dim Form As New Users
Form.MdiParent = Me
Form.Show()
End If
End Sub
I would like a subroutine to help me avoid repetiting this code for each menu item click events.

Ok, with a bit of help from This thread, you could use reflection/linq to create a new instance of the passed form from its' .Name string If you find a better way, I would be interested to learn myself.
Private Sub ButtonFormB_Click(sender As Object, e As EventArgs) Handles ButtonFormB.Click
CheckForm(FormB)
End Sub
Private Sub CheckForm(Frm As Form)
For Each OpnForm As Form In Application.OpenForms
If OpnForm Is Frm Then
OpnForm.BringToFront()
Exit Sub
End If
Next
Dim formType =
Reflection.Assembly.GetExecutingAssembly().GetTypes().Where(Function(a) a.BaseType = GetType(Form) AndAlso a.Name = Frm.Name).FirstOrDefault()
If formType IsNot Nothing Then
Dim NewForm As Form = CType(Activator.CreateInstance(formType), Form)
NewForm.Show()
End If
End Sub

Related

System.ObjectDisposedException when closing a form in vb.net

I am having a weird error and I am sure it is something very simple, but I can't for the life of me figure out what is going on. I thought I was opening and closing the forms properly, but it appears something is amiss. I am working with VS 2015. I have my program set to close when the last form is closed. There are two forms that I am using right now.
Dashboard
Public Class frmDashboard
Private Sub recExit_Click(sender As Object, e As EventArgs) Handles recExit.Click
Me.Close()
End Sub
Private Sub recMember_Click(sender As Object, e As EventArgs) Handles recMember.Click, lblMember.Click
'Create instance of Member Form
Dim memberForm As New frmMember
'Open an instance
memberForm.Show()
Me.Close()
'Using this code test if the form window is still open
For Each frm As Form In Application.OpenForms
MessageBox.Show(frm.Name)
Next
End Sub
End Class
Members Form
Public Class frmMember
Private Sub frmMember_Load(sender As Object, e As EventArgs) Handles Me.Load
ShowSpouse(rdoMarried.Checked)
End Sub
Private Sub ShowSpouse(ByRef isMarried As Boolean)
If isMarried Then
'Marital status is set to married lets show the extra spouse information
'Lets first make the form larger
Me.Size = New Size(793, 576)
'Now lets unhide the form
pnlSpouse.Visible = True
'pnlSpouse.Enabled = True
lblSpouse.Visible = True
'lblSpouse.Enabled = True
lineSpouse.Visible = True
'lineSpouse.Enabled = True
'Now lets move the buttons to their new location
btnApply.Location = New Point(624, 541)
btnExit.Location = New Point(710, 541)
Else
'Single is Selected
'Let's make sure all the spouse information is hidden
'Lets first make the form smaller
Me.Size = New Size(793, 358)
'Now lets hide the form and disable the controls
pnlSpouse.Visible = False
'pnlSpouse.Enabled = False
lblSpouse.Visible = False
'lblSpouse.Enabled = False
lineSpouse.Visible = False
'lineSpouse.Enabled = False
'Now lets move the buttons to their new location
btnApply.Location = New Point(624, 320)
btnExit.Location = New Point(710, 320)
End If
End Sub
Private Sub MaritalStatusChanged(sender As Object, e As EventArgs) Handles rdoSingle.CheckedChanged, rdoMarried.CheckedChanged
ShowSpouse(rdoMarried.Checked)
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Dim dashboard As New frmDashboard
'Open the dashboard
dashboard.Show()
'Close the member form
Me.Close()
End Sub
End Class
I havent added the database to it but eventually I will load data into the members form. When I click to open the members form it goes through and runs the code in the form load event for members form but then returns focus back to the dashboard form. Runs the Me.Close on the dashboard, but once it gets to End Sub thats when this exception gets thrown:
System.ObjectDisposedException was unhandled
Message: An unhandled exception of type 'System.ObjectDisposedException' occurred in System.Windows.Forms.dll
Additional information: Cannot access a disposed object.
Any help you guys can give would be greatly appreciated.

How can I use the .Show() method in such a way the user can't click other forms already opened in background?

Now i'm using a'jobdone' flag and the following behaviour (that it looks quite horrible to me...):
Dim NewLoginForm As New LoginClass
LoginClass.jobdone = False
NewLoginForm.Show()
While (LoginClass.jobdone = False)
Application.DoEvents()
End While
NewLoginForm.Close()
If I try to use ShowDialog() the behaviour is better but it's a problem to manage all the opening and closing windows (if the forms are many) and I notice that all the background already opened forms close themselves either if one ShowDialog() form is closed...
Thanks
Ran a quick test and this worked perfectly:
Public Sub ForceOpen(ByRef frm As Form)
frm.Show()
For Each otherForm As Form In Application.OpenForms
If otherForm Is frm Then
AddHandler frm.FormClosing, AddressOf BlockFormClosing
Else
otherForm.Enabled = False
End If
Next
End Sub
Public Sub BlockFormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
e.Cancel = True
End Sub
Public Sub EnableOpenForms()
For Each frm As Form In Application.OpenForms
frm.Enabled = True
RemoveHandler frm.FormClosing, AddressOf BlockFormClosing
Next
End Sub
The calling form will open the stay-open form with ForceOpen(FormStayOpen). When the stay-open form's conditions for allowing the user to close it have been satisfied, have it call EnableOpenForms().

List of Windows in vb.net application

I have an MDI application where I'm trying to get a list of open windows for a ComponentOne Ribbon Menu. Using VB .NET.
I have this sub for instantiating a new child form within the MDI container:
Private Sub newButton_Click(sender As Object, e As EventArgs) Handles newButton.Click
' Create a new instance of the child form.
Dim ChildForm As New MyProject.MyForm
'Make it a child of this MDI form before showing it.
ChildForm.MdiParent = Me
m_ChildFormNumber += 1
ChildForm.Text = "Window " & m_ChildFormNumber
ChildForm.Show()
End Sub
Then in another Sub for the ribbon menu I try to get the list of windows.
I tried this:
Dim frm As System.Windows.Window
For Each frm In My.Application.Windows
frmButton = New C1.Win.C1Ribbon.RibbonButton(frm.Title)
...
But I get a NullReferenceException on the System.Windows.Window collection.
So then I tried this:
For Each Window In My.Application.Windows
frmButton = New C1.Win.C1Ribbon.RibbonButton(Window.Title)
...
But with that, I get "overload resolution failed because no accessible 'new' can be called without a narrowing conversion" on the arguments for the new RibbonButton. If I turn Option Strict On, of course it says it disallows late binding.
So I guess ultimately I'm wondering why my Windows collection is empty, even if I've opened child forms.
Then even beyond that, why does the New RibbonButton accept frm.Title but not Window.Title.
NOTE (in case you were wondering)...the frmButton is a class object:
Friend WithEvents frmButton As C1.Win.C1Ribbon.RibbonButton
Thank you!
Thanks to clues from multiple sources, I was able to get it working. In case anyone else is wondering how, here's my sample code:
Public Class mainForm
Private m_ChildFormNumber As Integer
Friend WithEvents frmButton As C1.Win.C1Ribbon.RibbonButton
Private Sub newButton_Click(sender As Object, e As EventArgs) Handles newButton.Click
' Create a new instance of the child form.
Dim ChildForm As New ProofOfConcept.FormResize
'Make it a child of this MDI form before showing it.
ChildForm.MdiParent = Me
m_ChildFormNumber += 1
ChildForm.Text = "Window " & m_ChildFormNumber
ChildForm.Show()
End Sub
Private Sub windowMenu_Dropdown(sender As Object, e As EventArgs) Handles windowMenu.DropDown
Dim count As Integer = Me.MdiChildren.Length
windowMenu.Items.ClearAndDisposeItems()
For i As Integer = 0 To count - 1
frmButton = New C1.Win.C1Ribbon.RibbonButton
frmButton.Text = Me.MdiChildren(i).Text
frmButton.Tag = i
If MdiChildren(i) Is ActiveMdiChild Then
frmButton.SmallImage = My.Resources.test
End If
windowMenu.Items.Add(frmButton)
AddHandler frmButton.Click, AddressOf frmButton_Click
Next
End Sub
Private Sub frmButton_Click(sender As Object, e As EventArgs)
Dim Rb As C1.Win.C1Ribbon.RibbonButton = DirectCast(sender, C1.Win.C1Ribbon.RibbonButton)
Me.ActivateMdiChild(MdiChildren(CInt(Rb.Tag)))
Me.MdiChildren(CInt(Rb.Tag)).Focus()
End Sub
End Class
8 years later, this seems to be the only question on how to implement a Window menu, so here's my updated version for the standard MenuStrip control.
Friend WithEvents ChildWindowMenu As ToolStripMenuItem
Private Sub WindowMenu_DropDownOpening(sender As Object, e As EventArgs) Handles windowMenu.DropDownOpening
Try
windowMenu.DropDownItems.Clear()
For Each child In Me.MdiChildren
ChildWindowMenu = New ToolStripMenuItem With {
.Text = child.Text,
.Tag = child
}
If child Is ActiveMdiChild Then
ChildWindowMenu.Checked = True
End If
windowMenu.DropDownItems.Add(ChildWindowMenu)
AddHandler ChildWindowMenu.Click, AddressOf ChildWindowMenu_Click
Next
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub ChildWindowMenu_Click(sender As Object, e As EventArgs)
Try
CType(CType(sender, ToolStripMenuItem).Tag, Form).Activate()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

Check if form is Opened

I give this question for more knowledge. How can I know if the form is Opened in my application or not, in order not to open it again I mean not to create an instance of the same form while it's running
Dim frmCollection As New FormCollection()
frmCollection = Application.OpenForms()
If frmCollection.Item("Form2").IsHandleCreated Then
MsgBox("Yes Opened")
Else
Dim f As New Form2()
With f
.Text = "form2"
.Show()
End With
End If
if I executes this code many times it will create more instances of the form Form2
How can I check if this form is not already opened
You can try it like this:
Imports System.Linq ' need to add
If Application.OpenForms().OfType(Of Form2).Any Then
MessageBox.Show("Opened")
Else
Dim f2 As New Form2
f2.Text = "form2"
f2.Show()
End If
You can use the following code:
If myForm.IsHandleCreated then
myForm is open
End If
As an extension of the answers given (thank you, all), here's a simple way to activate or show:
Dim frmCollection = System.Windows.Forms.Application.OpenForms
If frmCollection.OfType(Of Form2).Any Then
frmCollection.Item("Form2").Activate()
Else
Dim newForm2 = New Form2
newForm2.Show()
End If
For more simplicity you may create a public static bool variable which will tell whether the form is opened or not. On form load event assign 'true' and on closed event assign 'false' value.
ANOTHER refactoring way from the one initiated by HumbleBeginnings:
Dim xChildWindows = Application.OpenForms.OfType(Of frmForm2)
If xChildWindows.Any Then
xChildWindows.First().Focus() 'Focus if exists
Else
Dim xfrmNew As New frmForm2() 'Open window if doeasn't exists
xfrmNew.MdiParent = Me
xfrmNew.Show()
End If
Hate to be a kill joy but some day some one is going to try and understand your code.
Dim frm as New frmDontknow
Dim frmCollection = System.Windows.Forms.Application.OpenForms
For i As Int16 = 0I To frmCollection.Count - 1I
If frmCollection.Item(i).Name = frm.Name Then
frmCollection.Item(i).Activate()
Exit Sub
End If
Next i
Then do the show etc as required?
Check if form is Opened, To validate if a form is open we use this method and function to be able to invoke from any form and use less code.
Example :
This will use it in a form with mdiContainer and a panel object with 3 buttons that shows the 3 windows form.
Imports System
Imports System.Reflection
Private Sub OpenWindowsForm(ByVal FormName As String)
Dim instForm As Form = Application.OpenForms.OfType(Of Form)().Where(Function(frm) frm.Name = FormName).SingleOrDefault()
If instForm Is Nothing Then
Dim frm As New Form
frm = DirectCast(CreateObjectInstance(FormName), Form)
frm.MdiParent = Me
Me.Panel1.Controls.Add(frm)
Me.Panel1.Tag = frm
frm.Show()
Else
instForm.Select()
instForm.WindowState = FormWindowState.Maximized
instForm.BringToFront()
End If
End Sub
Public Function CreateObjectInstance(ByVal objectName As String) As Object
Dim obj As Object
Try
If objectName.LastIndexOf(".") = -1 Then
objectName = [Assembly].GetEntryAssembly.GetName.Name & "." & objectName
End If
obj = [Assembly].GetEntryAssembly.CreateInstance(objectName)
Catch ex As Exception
obj = Nothing
End Try
Return obj
End Function
How to use in click events
Private Sub btnRegistro_Click(sender As Object, e As EventArgs) Handles btnRegistro.Click
OpenWindowsForm("Registro")
End Sub
Private Sub btnBusqueda_Click(sender As Object, e As EventArgs) Handles btnBusqueda.Click
OpenWindowsForm("Busqueda")
End Sub
Private Sub btnCalendario_Click_1(sender As Object, e As EventArgs) Handles btnCalendario.Click
OpenWindowsForm("Calendario")
End Sub
Here is an image of the Sample code
you can try this
Dim formText As String
Dim prevText As String
Private Sub OpenForm(ByVal frm As Windows.Forms.Form)
formText = frm.Text
If formText = prevText Then Exit Sub
CloseForms()
' Make it a child of this MDI form before showing it.
frm.MdiParent = Me
frm.Show()
frm.Location = New Point(0, 0)
prevText = formText
End Sub
Private Sub CloseForms()
For Each ChildForm As Form In Me.MdiChildren
ChildForm.Close()
Next
End Sub
Private Sub NewToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PayablesToolStripMenuItem.Click
OpenForm(frmPayables)
End Sub
For Each frm As Form In Application.OpenForms
If frm.Name = Form1.Name Then
MessageBox.Show("Opened")
End If
Next

Silverlight 5 Events

I am written in Silverlight 5 with VB.Net. I have a number of child windows. I want to catch the event when the user closes this window without clicking on any button. Please give me an example if possible. I prefer VB but I can translate C#.
Bob
You can subscribe to the Closing or Closed Events of you ChildWindows, in the Closing event you can check the DialogResult to see if it is True, if so let the Window Close otherwise Cancel the closing of the ChildWindow by setting e.Cancel to True. The example that I have here shows both events and will allow you to stop the ChildWindows Close.
Partial Public Class MainPage
Inherits UserControl
Dim child As ChildWindow1
Public Sub New()
InitializeComponent()
End Sub
Private Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
child = New ChildWindow1
AddHandler child.Closed, AddressOf ChildClosed
AddHandler child.Closing, AddressOf ChildClosing
child.Show()
End Sub
Private Sub ChildClosed(sender As Object, e As EventArgs)
Dim result As Boolean? = CType(sender, ChildWindow).DialogResult
If IsNothing(result) Then
'Do something if DialogResult is Nothing You can not cancel close with this event
ElseIf Not result Then
'Do what you want when the Cancel Button is clicked
ElseIf result Then
'Do what you want when the Ok Button is clicked
End If
End Sub
Private Sub ChildClosing(sender As Object, e As ComponentModel.CancelEventArgs)
Dim result As Boolean? = CType(sender, ChildWindow).DialogResult
If IsNothing(result) Then
e.Cancel = True 'This will cancel the ChildWindows Close and leave it open
ElseIf Not result Then
'Do what you want when the Cancel Button is clicked
ElseIf result Then
'Do what you want when the Ok Button is clicked
End If
End Sub
End Class