Check if form is Opened - vb.net

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

Related

Form3 linked to Form2. Values not updating upon change

i am creating a windows forms app with 3 forms.
I am able to send values and update them timely between form1 and form2.
But i have problems with updating values from form3 to form2.
My code in form2 is as follows:
Public Sub GetValues_Form3()
xlExcelLink = Form3.LoadProjDB()
If xlExcelLink Is Nothing Then
MsgBox("Projekt Datenbank fehlt." & vbNewLine & "Bitte wählen Sie in den Optionen erneut die Projektdatenbank aus.", , "Fehler")
Form1.ib_OptionsTab_Click(Form1.ib_OptionsTab, Nothing) 'Opens Form3
End If
End Sub
My code in Form 3 is as follows:
Private Sub ib_ProjDB_Browse_Click(sender As Object, e As EventArgs) Handles ib_ProjDB_Browse.Click
If OpenFileDialog1.ShowDialog() <> DialogResult.Cancel Then
tb_Excel.Text = OpenFileDialog1.FileName
End If
End Sub
Function LoadProjDB() As String
Dim Form3_ExcelPath As String = tb_Excel.Text
MsgBox(Form3_ExcelPath)
If Form3_ExcelPath IsNot Nothing And System.IO.File.Exists(Form3_ExcelPath) Then
MsgBox(Form3_ExcelPath)
Form2.Label1.Text = Form3_ExcelPath
Return Form3_ExcelPath
Else
Return Nothing
End If
End Function
I have a default file path. I check if the path exists.
If it doesnt exist, i want my form2 to open form3, where i can select the new file.
After form3 is closed, i get the path string from form3 in form2, and it checks if the string is nothing.
If it is nothing, it will open form3 again.
The problem here is:
I am able to select a new file and it is displaying correctly in form3.
But form2 is not updating its vale from form3.
It still has the first value that it got from form3.
Please help.
Thank you.
Edit1:
Now I am trying to run Subs and Function in Form2 from Form1.
It seems the variables are changing temporarily when executed, but the functions are not being triggered by my action.
I cant seem to find a solution for it till now.
Edit 2:
#Idle_Mind
Im using a public sub which handles button click in form1 to display form3.
Public Sub ib_OptionsTab_Click(sender As Object, e As EventArgs) Handles ib_OptionsTab.Click
If ib_OptionsTab.Tag = 0 Then
Form3_in_Panel()
ElseIf ib_OptionsTab.Tag = 1 Then
Form3_Out_Panel()
End If
End Sub
Form3 is the oped using this function in form1.
Function Form3_in_Panel()
If Form3_Load = True Then
Dim f3 As New Form3
f3.TopLevel = False
f3.Dock = DockStyle.Fill
pnl_Fill.Controls.Add(f3)
f3.Visible = True
f3.BringToFront()
Form3_Load = False
frm3 = pnl_Fill.Controls.Item("Form3")
Else
pnl_Fill.Controls.Item("Form3").Visible = True
End If
ib_OptionsTab.Tag = 1
Return Nothing
End Function

vb.net Find Form

In the Windows, the native Notepad program has a find form. Basically When the user types and hits 'Find Next', the program proceeds to find the text while keeping the focus on the Find form. This way the user can keep hitting the 'Enter' key or the button and still have the text highlighted while the form is focused.
My problem is that I have a different form for the "Search" feature and whenever the user hits "Enter" the text is found and the focus is set on the TextBox but when the user hits "Enter" again, the text gets edited because of the focus.
Currently, I'm using Regex to do this and I am using a WPF TextBox using HostElement:
Private Function GetRegExpression() As Regex
Dim result As Regex
Dim regExString As [String]
regExString = txtbx_Find.Text
If matchCaseCheckBox.Checked Then
result = New Regex(regExString)
Else
result = New Regex(regExString, RegexOptions.IgnoreCase)
End If
Return result
End Function
Private Sub FindText()
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
If isFirstFind Then
regex = GetRegExpression()
match = regex.Match(TheTextBox.Text)
isFirstFind = False
Else
match = regex.Match(TheTextBox.Text, match.Index + 1)
End If
If match.Success Then
Dim row As Integer = TheTextBox.GetLineIndexFromCharacterIndex(TheTextBox.CaretIndex)
MoveCaretToLine(TheTextBox, row + 1)
TheTextBox.SelectionStart = match.Index
TheTextBox.SelectionLength = match.Length
TheTextBox.Focus()
Me.Focus()
Else
MessageBox.Show([String].Format("Cannot find ""{0}"" ", txtbx_Find.Text), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)
isFirstFind = True
End If
End Sub
Private Sub btn_FindNext_Click(sender As Object, e As EventArgs) Handles btn_FindNext.Click
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
FindText()
'theTextBox.Focus()
End Sub
I want it to be just like Notepad where the user hits "Enter" and keeps focus on the Find Form while selecting the text. How can this be achieved?
I think you should catch "keyup" event of your form like this :
Class MainWindow
Private Sub Window_KeyUp(sender As System.Object, e As System.Windows.Input.KeyEventArgs) Handles MyBase.KeyUp
If e.Key = Key.Enter Then
FindNext()
End If
End Sub
Private Sub btn_FindNext_Click(sender As Object, e As EventArgs) Handles btn_FindNext.Click
FindText()
End Sub
Private Sub FindNext()
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
FindText()
'theTextBox.Focus()
End Sub
End Class

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

How to get values from a dialog form in VB.NET?

I have a "frmOptions" form with a textbox named "txtMyTextValue" and a button named "btnSave" to save and close the form when it's clicked,
then, I'm showing this dialog form "frmOptions" when a button "btnOptions" is clicked on the main form "frmMain", like this
Private Sub btnOptions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOptions.Click
ShowOptionsForm()
End Sub
Private Sub ShowOptionsForm()
Dim options = New frmOptions
options.ShowDialog()
End Sub
How can I get in the main form "frmMain" the value inserted in the textbox "txtMyTextValue" when the "btnSave" is clicked?
You want to capture the information from the dialog only if the result is OK (user presses Save instead of Cancel or closes the dialog some other way), so do this:
Private Sub ShowOptionsForm()
Dim options = New frmOptions
' Did the user click Save?
If options.ShowDialog() = Windows.Forms.DialogResult.OK Then
' Yes, so grab the values you want from the dialog here
Dim textBoxValue As String = options.txtMyTextValue.Text
End If
End Sub
Now inside of your dialog form, you need to set the result Windows.Forms.DialogResult.OK when the user clicks the button that corresponds to the OK action of the dialog form, like this:
Public Class frmOptions
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
' Set the result to pass back to the form that called this dialog
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
End Class
The simplest method is to add a public property to the frmOptions form that returns an internal string declared at the global level of the frmOptions
Dim strValue As String
Public Property MyStringValue() As String
Get
Return strValue
End Get
End Property
Then, when your user clicks the OK button to confirm its choices you copy the value of the textbox to the internal variable
Private Sub cmdOK_Click(sender As Object, e As System.EventArgs) Handles cmdOK.Click
strValue = txtMyTextValue.Text
End Sub
Finally in the frmMain you use code like this to retrieve the inserted value
Private Sub ShowOptionsForm()
Using options = New frmOptions()
if DialogResult.OK = options.ShowDialog() Then
Dim value = options.MyStringValue
End If
End Using
End Sub
I prefer to avoid direct access to the internal controls of the frmOptions, a property offer a indirection that could be used to better validate the inputs given by your user.
You can use Events to take care of this. With this approach the Settings Form does not have to be Modal and the user can click the Save Button at any time.
In frmOptions:
'You can expand the signature to take more than just a single String.
Friend Event SavedOptions(ByVal strData As String)
Private Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSave.Click
RaiseEvent SavedOptions(txtMyTextValue.Text)
End Sub
In frmMain:
Private Sub ShowOptionsForm()
Dim options = New frmOptions
AddHandler options.SavedOptions, AddressOf OnOptionsSave
options.ShowDialog()
End Sub
Private Sub OnOptionsSave(ByVal strData As String)
'Or whatever you want to do on frmMain with Options Data.
MsgBox(strData)
End Sub
You can access the value from the frmOptions instance. However, this breaks the law of demeter.
You should expose the value with a property within your class.
Public Class frmOptions
Public ReadOnly Property MyTextValue As String
Get
Return Me.txtMyTextValue.Text
End Get
End Property
End Class
Then you can access the value:
Private Sub ShowOptionsForm()
Dim options = New frmOptions
Dim frmOptionTextValue As String
Dim frmOptionsDiagResult As DialogResult
frmOptionsDiagResult = options.ShowDialog()
If frmOptionsDiagResult = Windows.Forms.DialogResult.OK Then
frmOptionTextValue = options.MyTextValue
Else
'...
End If
End Sub
Finally, if you are using a Dialog then make sure to set the Dialog Result for the button.

Calling external user control by its name

I have one panel (Panel1), two combo boxes (ComboBox1, ComboBox2) and one button (Button1) all in same form (Form1).
When the button is clicked:
Private Sub Button1_Click(sender As Object, e As EventArgs)
Dim a as String = ComboBox1.SelectedValue() & Combobox2.SelectedValue()
AddUserControl(a)
End Sub
value of a is the name of an external user control for instance p1k1.
Can I add an external user control named p1k1 to Panel1 in Form1 using following method?
Private Sub AddUserControl(ByVal a As String)
Panel1.Controls.Add(a)
End Sub
What should I do to make this work?
Usually I would use:
Panel1.Controls.Add(new p1k1)
You'll need to use reflection to do this. Something like this:
Private Sub AddUserControl(ByVal a As String)
Dim controlType As Type = Type.GetType(a)
If controlType Is Nothing Then
Throw New ArgumentException(String.Format("""{0}"" is not a valid type. Type names are case sensitive.", a))
ElseIf Not controlType.IsSubclassOf(GetType(Control)) Then
Throw New ArgumentException(String.Format("""{0}"" does not inherit from Control. Only Controls can be added to the control collection.", a))
End If
Dim newControl As Control = Activator.CreateInstance(controlType)
If newControl Is Nothing Then
Throw New ArgumentException(String.Format("Unspecified error when creating control of type ""{0}"".", a))
End If
Panel1.Controls.Add(newControl)
End Sub
i found my answer finally...
Private Sub AddUserControl(ByVal a As String)
Dim nmspace As String = "mynamespace"
Dim t As Type = Assembly.GetExecutingAssembly().GetType(nmspace & "." & a)
Dim o As Control = Activator.CreateInstance(t)
Panel1.Controls.Add(o)
End Sub