I have two forms. First form is used to display a set of record and second form is used to edit the particular record. I called the second form using frm.ShowDialog(). Inside that form I got a button to call the OpenFileDialog. When I press OK or Cancel, then the second form dispose together with the OpenFileDialog. I'm pretty should that my code is correct, but it was the ShowDialog() problem. Anyone have idea on this issue?
This is how i called the second form from the first form to display the Information.
Private Sub btnViewOrganizationEdit_Click(sender As Object, e As EventArgs) Handles btnViewOrganizationEdit.Click, dgvOrganization.DoubleClick
Dim selectedOrganization As New Organization
'check permission because double click
If dgvOrganization.RowCount > 0 Then
strOrganizationID = dgvOrganization.SelectedRows.Item(0).Cells(0).Value
selectedOrganization = helperOrganizationCKJ.getOrganizationByID(strOrganizationID)
frmEditOrganizationCKJ.objOrganization = selectedOrganization
frmEditOrganizationCKJ.ShowDialog()
iniGridView()
End If
End Sub
This is how i called the OpenFileDialog.
Private Sub btnEditOrganizationImage_Click(sender As Object, e As EventArgs) Handles btnEditOrganizationImage.Click
dlgImage.Filter = ""
Dim codecs() As ImageCodecInfo = ImageCodecInfo.GetImageEncoders()
Dim sep As String = String.Empty
For Each c As ImageCodecInfo In codecs
Dim codecName As String = c.CodecName.Substring(8).Replace("Codec", "Files").Trim()
dlgImage.Filter = String.Format("{0}{1}{2} ({3})|{3}", dlgImage.Filter, sep, codecName, c.FilenameExtension)
sep = "|"
Next
dlgImage.FilterIndex = 5
If dlgImage.ShowDialog(Me) = DialogResult.OK Then
'Get the image name
Dim img = dlgImage.FileName
picEditOrganizationImage.Image = System.Drawing.Bitmap.FromFile(img)
End If
End Sub
The frmEditOrganizationCKJ just dispose together with the dispose of OpenFileDialog.
Probably you have copy/pasted your btnEditOrganizationImage from a button that has the DialogResult property set to something different than DialogResult.None.
This triggers the closing action for your modal form and the fix is really simple.
Set the property DialogResult for the btnEditOrganizationImage to DialogResult.None
From MSDN on Button.DialogResult
If the DialogResult for this property is set to anything other than
None, and if the parent form was displayed through the ShowDialog
method, clicking the button closes the parent form without your having
to hook up any events. The form's DialogResult property is then set to
the DialogResult of the button when the button is clicked
Related
Here's my problem:
I have a form with a treeview.
That treeview shows all:
other forms in my project as parents
all buttonnames as childs
all buttontags as childs of the buttonnames.
When i select a buttonname in the treeview i have the selection presented as
(textbox1 with the buttonname)
(textbox2 with the buttontag)
(textbox3 with the formname)
I have 1 empty textbox which i want to fill manually, to update the buttontag from the button selected in the treeview.
Either way, all code I have tried ain't updating anything.
This is the code so far, but doesn't seem to work...
My Code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim asm = System.Reflection.Assembly.GetExecutingAssembly
Dim myTypes As Type() = asm.GetTypes()
Dim frm As Form
For Each t As Type In myTypes
If t.IsSubclassOf(GetType(System.Windows.Forms.Form)) AndAlso TextBox1.Text = t.Name Then
frm = CType(Activator.CreateInstance(t), Form)
frm.Hide()
Dim thisButtonName As String = TextBox3.Text ' This is the name of the button I'm looking for
Dim thisButtonName2 As String = TextBox2.Text ' this is the new tag name for that button
' Loop all controls in this form
For Each ctrl As Control In Controls
' Is this control a button
If TypeOf (ctrl) Is Button Then
' Is this the correct button
If CType(ctrl, Button).Name = thisButtonName Then
CType(ctrl, Button).Tag = thisButtonName2
End If
End If
Next
End If
Next
TreeView1.Nodes.Clear()
For Each formprop In My.Forms.GetType.GetProperties
Dim node = Me.TreeView1.Nodes.Add(formprop.Name)
Dim form As Form = CType(formprop.GetValue(My.Forms, Nothing), Form)
ControlsTree(node, form.Controls)
Next
End Sub
I think there are two basic problems here:
Your loop For Each ctrl As Control In Controls is not iterating over the controls in the other form object referenced by the frm variable. The Controls property is going to default to this form's set of Controls, not frm.Controls.
It seems like you are trying to change the Tag in the definition of that class at run-time. That is not possible, AFAIK, especially in what you're trying here. Each time you create a new instance of that form object, you are going to get that object initialized as how it was compiled. You can change the Tag values of a running instance of the object, but you can't change the default values of the class without using a technique like dependency injection.
I have a MDI Parent form which has a menustrip for the application. My application startup file is the MDI Parent form which on load calls a child login form. Code as below:
Dim myForm As Form = New Login
Dim formResult As DialogResult = myForm.ShowDialog()
If formResult = Windows.Forms.DialogResult.OK Then
If LoginSucceeded = True Then
Me.tabMainMenu.Visible = True
ApplyUserAccess(eApp.DataAccess.DAL_UserSettings.SelectMenuSettingByUserID(glbUserID))
myForm.Dispose()
End If
End If
The menustrip has a Logout label which when clicked disables the menu strip and displays the login form again.
The boolean field LoginSucceeded determines a successful validation of the user credentials and sets the menu according to the access given to that user. My problem is the first time the main menu on the MDI parent is set properly based on the user's access. After logging out and logging in again, i wanted to set the main menu accordingly again which is not happening.
The Form_Load event on the MDI Parent is being executed only once.
Any tips of re-painting the MDI parent when it receives focus the 2nd time onwards.
Thanks,
ZK
My code for the Logoff is as below:
Dim blnLogout As DialogResult = MessageBox.Show("Are You Sure You Want To Logout?", "eApp", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If blnLogout = Windows.Forms.DialogResult.Yes Then
SetToolbarMenuStyle()
tabMainMenu.Visible = False
LoginSucceeded = False
blnShowLoginTab = True
Dim myForm As Form = New Login
myForm.MdiParent = Me
myForm.WindowState = FormWindowState.Normal
myForm.Show()
End If
Move your login code to its own method in your main form so you can call it multiple times:
Public Class Form1
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown ValidateLogin()
ValidateLogin()
End Sub
Private Sub LoginLogoutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LoginLogoutToolStripMenuItem.Click
ValidateLogin()
End Sub
Private Sub ValidateLogin()
' disable appropriate main form elements so they can't access anything:
Me.tabMainMenu.Visible = False
Using myForm As New Login
If myForm.ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
' login succeeded: re-enable main form elements
Me.tabMainMenu.Visible = True
ApplyUserAccess(eApp.DataAccess.DAL_UserSettings.SelectMenuSettingByUserID(glbUserID))
Else
MessageBox.Show("Login Failed")
End If
End Using
End Sub
End Class
You also don't need the "LoginSucceeded" variable. You can pass a success/failure back to the main form by setting DialogResult to OK in your Login form:
Public Class Login
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If True Then ' <-- perform your check
Me.DialogResult = Windows.Forms.DialogResult.OK ' only return OK if login has succeeded
End If
End Sub
End Class
Here are presumptions on your code, I'm guessing you added the code about on the Form.Load event. The Form.Load event only gets raised when the form is shown for the first time.
According to MSDN
Form.Load Event
Occurs before a form is displayed for the first time.
And now, when you Log-Off, you're setting the visibility of the form to false. So what I suggest is you move your code from the Form.Load event to the Form.VisibleChanged event.
According to MSDN
Form.Load Event
Occurs when the Visible property value changes.
I am writing a program using a database for customers and technicians. The main form (CustomerIncidents) has a toolstripbutton that opens a different form to (SearchByState) where the user inputs a state code and looks for any incidents.
If the user clicks into one of the datagrid cells I want that customers information to be stored in the TAG so that when the form is closed using the OK button that it will show back up in the main form (CustomerIncidents).
Edited 03/11/14 12:21pm
The problem is in the Main Form. When I click the OK button in the Second Form it tries to convert the DialogResult Button to a String. I can't figure out how to fix it.
Customer Form (Main Form) Opens to Secondary Form
Private Sub btnOpenState_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnOpenState.Click
Dim frmSearchState As New FindCustomer
----->>Dim selectedButton As DialogResult = frmSearchState.ShowDialog()
If selectedButton = Windows.Forms.DialogResult.OK Then
CustomerIDToolStripTextBox.Text = frmSearchState.Tag.ToString
End If'
Search By State Form (Secondary Form) Or "Child Form"
Private Sub btnOk_Click(message As String, ByVal e As DataGridViewCellEventArgs) Handles btnOk.Click
message = CustomersDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString
Me.Tag = message
Me.DialogResult = DialogResult.OK
End Sub
The click event for a button does not have a DataGridViewCellEventArgs parameter, and will throw an exception when you try to use it.
You don't need to use the Tag property since you can just create your own property.
In your child form, create a property called GridValue:
Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click
If dgv.CurrentCell Is Nothing OrElse dgv.CurrentCell.Value Is Nothing Then
MessageBox.Show("A cell needs to be selected.")
Else
Me.DialogResult = DialogResult.OK
End If
End Sub
Public ReadOnly Property GridValue As String
Get
Return dgv.CurrentCell.Value.ToString
End Get
End Property
In your parent form, you can now access your information:
Using frmSearchState As New FindCustomer
If frmSearchState.ShowDialog(Me) = DialogResult.Ok Then
CustomerIDToolStripTextBox.Text = frmSearchState.GridValue
End If
End Using
My personal approach for doing this kind of stuff is to create a public property in the child form, having the same type as the DATA you want to take back to your main form. So instead of storing DataGridView's reference in Tag property, you should really be storing the actual value that was there in the cell that the user clicked on.
For example, if your DGV cell has a string value in it, you could do something like:
Public Readonly Property StateName As String
Get
If YourDGV.SelectedCell IsNot Nothing Then
Return YourDGV.SelectedCell.Value
Else
Return ""
End If
End Get
End Property
(I have written that code by hand, so there may be some syntax problems, but you should be able to get the idea.)
You can now use ShowDialog() in the main form to bring up this child form and upon OK or Cancel, you could check the value of StateName property of your child form to get this value. The thing to remember here is that closing a form doesn't dispose off all its constituent controls and properties and therefore you can access them even after the form has finished ShowDialog() call.
The below subroutine, when called using a mouse click, successfully creates and then removes a control. but it doesn't create it a second time. I'm assuming it is because the label is not longer dimensioned as public. ie Dim lblDebug1 As New Label is at the top variable section of the form.
However when I put Dim lblDebug1 As New Label in the subroutine the dispose request doesn't work. Is there someway that I can keep creating and disposing a control?
In the below sub, booleanDebug is used to switch back and forth between creating it and disposing it. Thanks in advance.
Dim lblDebug1 As New Label
booleanDebug = Not booleanDebug
If booleanDebug Then
Me.Controls.Add(lblDebug1)
lblDebug1.BackColor = Color.BlueViolet
Else
lblDebug1.Dispose()
End If
Ensure the label has a global context. Within the form that owns it and that you have all the appropriate size and coordinates information and visibility set.
Here is some sample code that worked for me. First just create a new windows form then add a button control in the middle of the form then use the following code.
Public Class Main
Private labelDemo As Windows.Forms.Label
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.SuspendLayout()
If labelDemo Is Nothing Then
labelDemo = New Windows.Forms.Label
labelDemo.Name = "label"
labelDemo.Text = "You Click the Button"
labelDemo.AutoSize = True
labelDemo.Left = 0
labelDemo.Top = 0
labelDemo.BackColor = Drawing.Color.Violet
Me.Controls.Add(labelDemo)
Else
Me.Controls.Remove(labelDemo)
labelDemo = Nothing
End If
Me.ResumeLayout()
End Sub
End Class
Once you've Disposed a control, you can't use it any more. You have two choices here:
Choice 1: Just Remove the control from the form rather than disposing it:
'Top of the file
Dim lblDebug1 As New Label
'Button click
booleanDebug = Not booleanDebug
If booleanDebug Then
lblDebug1.BackColor = Color.BlueViolet
Me.Controls.Add(lblDebug1)
Else
Me.Controls.Remove(lblDebug1)
End If
Choice 2: Create a new control object each time
'Top of the file
Dim lblDebug1 As Label
' ^ No "New".
'We just want an object reference we can share at this point, no need for an instance yet
'Button click
booleanDebug = Not booleanDebug
If booleanDebug Then
lblDebug1 = New Label()
lblDebug1.BackColor = Color.BlueViolet
Me.Controls.Add(lblDebug1)
Else
lblDebug1.Dispose()
End If
I'm adding the form controls on loading the form manually:
Me.FieldI = New TextBox()
Me.FieldI.Location = New System.Drawing.Point(50, 10)
Me.FieldI.Name = "FieldI"
Me.FieldI.Size = New System.Drawing.Size(40, 20)
Me.FieldI.TabIndex = 5
Me.Conversion.Controls.Add(Me.FieldI)
[..]
When I close the form window and reopen it, the control is still there (with the old .Text content , because its an textbox in this case).
I would like to remove the controls that have been created while form loading on the form close event, to prevent doubling the elements on my form.
How can I achieve this?
edit
Form closing code looks following (just showing up the main form back):
Private Sub Form1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.FormClosing
Main.Show()
End Sub
The problem here is that the form is not being disposed, so when you open it again the controls are still there from the last time it was opened.
Try the following:
Using frm = New subForm()
frm.ShowDialog()
End Using
The variable frm will be disposed after the using.
Also...
You can also provide feedback from a dialog, to check whether the form was successful or not. For example:
Dim frm As New subForm()
If frm.ShowDialog = DialogResult.OK Then
'YAY!
Else
'Something failed
End If