SaveFileDialog.ShowDialog not showing on a form from .dll - vb.net

I have a windows form that contains a SaveFileDialog as a component. This form is called from a library (.dll). When you click on btnExport you should see the save file dialog window.
My problem is that SaveFileDialog1.ShowDialog doesn't show any window to select the directory path.
This is my code:
Private Sub btnExport_Click(sender As Object, e As EventArgs) Handles btnExport.Click
SaveFileDialog1.Filter = "XLS File|*.xls"
SaveFileDialog1.Title = "SaveFileDialog title"
Try
' this should open the dialog
If Me.SaveFileDialog1.ShowDialog() = DialogResult.OK Then
' Do something
Else
' This is a custom function to show messages
ShowCustomMessage("Error opening SaveFileDialog")
End If
Catch ex As Exception
' Show exception
End Try
End Sub

Your code works. You could try the following -
Try removing the Try-Catch-End Try as it could be hiding an error from you since you didn't implement anything to handle the Catch.
Try specifying the Owner object when calling ShowDialog() to ensure it is not going behind your main form.
Me.SaveFileDialog1.ShowDialog(Me) ...

Related

Parent form sometimes does not close (Only in Windows 10)

My main form is frmInvoice. This sub is located inside frmInvoice.
This is one of the Subs that sometimes causes frmDark to not close. frmLookup does not display when this happens. frmDark just stays there covering frmInvoice. It's like it doesn't reach the call to frm.ShowDialog(frmDark), cause when I press the lookup key, it displays the frmLookup, but upon closing frmLookup, frmDark is still there.
No exception is being raised.
Note that this only happens in Windows 10. In Windows 8/7, this never happened. What am I missing?
This happens at different times. Sometimes I could press the lookup key for 20 times and it will display fine. Sometimes, after 1 press of the lookup key and this happens.
Private Sub ItemLookup()
Try
Using frmDark As New Form
With frmDark
.ShowInTaskbar = False
.Icon = Me.Icon
.FormBorderStyle = Windows.Forms.FormBorderStyle.None
.BackColor = Color.Black
.Opacity = 0.95
.WindowState = FormWindowState.Maximized
.Show(Me)
Using frm As New frmLookup
With frm
.Icon = Me.Icon
.ShowDialog(frmDark)
frmDark.Close()
If .DialogResult = Windows.Forms.DialogResult.OK Then
' Do stuff here
End If
End With
End Using
End With
End Using
Catch ex As Exception
ErrMsg(ex)
End Try
End Sub
UPDATE: I'm using .Net Framework 4.8
Thanks
I would suggest rearranging the code like so:
Dim lookupResult As DialogResult
Using frmDark As New Form With {.ShowInTaskbar = False,
.Icon = Me.Icon,
...}
frmDark.Show(Me)
Using frm As New frmLookup With {.Icon = Me.Icon}
lookupResult = frm.ShowDialog(frmDark)
End Using
End Using
If lookupResult = DialogResult.OK Then
'...
End If
Because that code exits the Using block that created frmDark, there should be no way that it can't close.
Also, instead of using a vanilla Form and configuring it on demand, I would suggest that you create a dedicated form type to use as the overlay in that scenario. You can then get rid of all the property assignments.
Having a dedicated overlay form would also allow you to reconfigure things significantly and, in my opinion, better. The overlay form could have a property of type Form. You main form could then create a frmLookup instance and assign it to that property, than call ShowDialog on the overlay form. In the Shown event handler of the overlay form, it could then call ShowDialog on the form in that property. When that call returns, it could assign the result to its own DialogResult property and close itself. The main form would then just get the result from calling ShowDialog on the overlay. That might look like this:
Public Class OverlayForm
Public Property DialogueForm As Form
Private Sub OverlayForm_Shown(sender As Object, e As EventArgs) Handles Me.Shown
DialogResult = DialogueForm.ShowDialog()
End Sub
End Class
and this:
Public Class MainForm
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using dialogue As New DialogueForm,
overlay As New OverlayForm With {.DialogueForm = dialogue}
If overlay.ShowDialog() = DialogResult.OK Then
MessageBox.Show("OK")
End If
End Using
End Sub
End Class

vb.net cannot access a disposed object when opening form

I have a program that we use to run different reports. Based on the menu option chosen, I open the same form that lists the reports based on the menu option.
(There are also different options and functionalities in the program, not just one form).
When clicking a menu option, I have the following bit of code
Private Sub ReportsToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles ReportsToolStripMenuItem1.Click
FormLocation = "F_Legal"
FormName = "Legal"
PrepareForm(F_Select_Report)
End Sub 'ReportsToolStripMenuItem1_Click
Where F_Select_Report the form is that is opened.
Private Sub PrepareForm(formName As Form)
Cursor = Cursors.WaitCursor
For Each Form In Me.MdiChildren
Form.Close()
Next
formName.MdiParent = Me
formName.Height = Me.Height
formName.Width = Me.Width
formName.Show()
Cursor = Cursors.Arrow
End Sub 'PrepareForm
This bit is called, closing all other opened forms, and then open the form that is called.
This works fine on the first time I try and open a form, but on the second try, I get an error message saying
Cannot access a disposed object.
And then on the third try, it opens the form again.
How would I fix this up?
Thanks a lot
Form.Close implicitly calls Form.Dispose
So if the formName is an MdiChild it gets disposed in the For Each loop.
Then, on the next line your code attempts to assign to its MdiParent property and there the error occurs.
So you need to skip it when closing MDI children like this:
For Each Form In Me.MdiChildren
If Not Form Is formName Then Form.Close
Next
Given your code I think it is better to close the children before showing the F_Select_Report form. I.e. move the For Each loop as is to the top of the ReportsToolStripMenuItem1_Click handler.
Not sure if it is the best/nicest solution, but found a solution to this.
Instead of 1 Sub that does both closes all open forms, and then opens the new one, I split it out over 2 Subs.
Close all open ones
Private Sub CloseAllForms()
For Each Form In Me.MdiChildren
Form.Close()
Next
End Sub 'CloseAllForms
And then open the new form
Private Sub PrepareForm(formName As Form)
Cursor = Cursors.WaitCursor
Try
formName.MdiParent = Me
formName.Height = Me.Height
formName.Width = Me.Width
formName.Show()
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Cursor = Cursors.Arrow
End Sub 'PrepareForm
Now it works as needed.

Get image location using a drag and drop

I have a drag and drop event to get images into a picture box. I need to get the image location to string to store on my database. I can get the location if I use a OpenFileDialog, but if I use a drag and drop, I can't seem to get it. Here is my code:
Private Sub picCategoryImage_DragEnter(sender As Object, e As DragEventArgs) Handles picCategoryImage.DragEnter
'Procedure to copy the dragged picture from the
'open window
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
'If the file explorer is open, copy the picture to the box
e.Effect = DragDropEffects.Copy
picCategoryImage.BorderStyle = BorderStyle.FixedSingle
TextBox1.Text = picCategoryImage.ImageLocation
Else
'otherwise, don't take action
e.Effect = DragDropEffects.None
btnDeleteImage.Visible = False
End If
End Sub
Private Sub picCategoryImage_DragDrop(sender As Object, e As DragEventArgs) Handles picCategoryImage.DragDrop
'Procedure to select the pictue and drag to picturebox
Dim picbox As PictureBox = CType(sender, PictureBox)
Dim files() As String = CType(e.Data.GetData(DataFormats.FileDrop), String())
If files.Length <> 0 Then
Try
picbox.Image = Image.FromFile(files(0))
btnDeleteImage.Visible = True
picbox.BorderStyle = BorderStyle.None
picCategoryImage.BringToFront()
btnDeleteImage.BringToFront()
Catch ex As Exception
MessageBox.Show("Image did not load")
End Try
End If
End Sub
As suggested by Plutonix, you're already using the file path so you've already got it. That's how Image.FromFile is able to create an Image from a file. If you mean that you need to be able to get the path later then you have two main choices:
Do as you're doing and store the path in a member variable for later use.
Instead of calling Image.FromFile and setting the Image of the PictureBox, just call the Load method of the PictureBox. You can then get the path from the ImageLocation property.
I would actually suggest using option 2 regardless, because it has the added advantage of not locking the file the way your current code does.

Remove the windows form controls on exit

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

VB.NET 2010 Passing Picture from OpenFile Dialog Box to another form

I am creating a loan program that opens a Custom Form Dialog Box, you choose the picture, click open and then need to pass it to another form to use after hitting OK from the Dialog Box. This is my code when I click the Logo File button from my custom Dialog Form.
The Form is called Dialog Form and I need to send the picture to the NewLoanCaculatorForm to populate a picture area in the form.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogoFile.Click
Dim mystream As Stream = Nothing
'Open the File to pickup icon for Loan Calculator
Dim OpenFileDialog1 As New OpenFileDialog
'Set up and display the open File Dialog
With OpenFileDialog1
'Begin in the current Directory
.InitialDirectory = "C:\"
.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
End With
If OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
mystream = OpenFileDialog1.OpenFile()
If (mystream IsNot Nothing) Then
' I believe the coded goes here but I'm stuck
End If
Catch Ex As Exception
MessageBox.Show("Cannot read file from disk. Original error: " & Ex.Message)
Finally
' Check this again, since we need to make sure we didn't throw an exception on open.
If (mystream IsNot Nothing) Then
mystream.Close()
End If
End Try
End If
End Sub
This is how I usually do things like this:
Create global variable in the DialogForm:
Public Property sPath as String
or
Public Property imgLogo as Image
To get the Image do this:
imgLogo = Image.FromFile(OpenFileDialog1.FileName)
Or simply do:
sPath = OpenFileDialog1.FileName
instead of
mystream = OpenFileDialog1.OpenFile()
Then when you have done this you close the form by clicking the OK button or whatever you call it.
Then in your main form NewLoanCaculatorForm where you call DialogForm you simply do:
img = DialogForm.imgLogo
or
path = DialogForm.sPath
img = Image.FromFile(path)
Depending on which way you stored the info in the DialogForm.
Also, if you are looking for images I would recommend you not to have .txt in your filter. That would seriously ruin the execution.