How can I prevent an exception when I cancel an openfiledialog? - c#

My program has a button which when clicked opens an openfiledialog to choose a picture:
private string ChoosePicture()
{
fDialog.Title = "Select Picture";
fDialog.Filter = "Image Files (*.bmp, *.gif, *.jpg)|*.bmp; *.gif*;*.jpg";
fDialog.InitialDirectory = "C:";
fDialog.ShowDialog();
fDialog.AddExtension = true;
fDialog.CheckFileExists = true;
fDialog.CheckPathExists = true;
//returns a string for the directory
return fDialog.FileName.ToString();
}
Using a check on the dialogresult box hasn't resolved my issue either:
fDialog.AddExtension = true;
fDialog.CheckFileExists = true;
fDialog.CheckPathExists = true;
DialogResult res = fDialog.ShowDialog();
if (res == DialogResult.OK)
{
//returns a string for the directory
return fDialog.FileName.ToString();
}
return null;
The code works if I do choose a picture and complete the file selection. However if I cancel the process at any point in between I get the exception "The path is not of a legal form". I am not sure which part I imagine I could take care of this with a try-catch, however I'm not positive which part is causing the issue? If I put a try catch around the call to the ChoosePicture() method, I can at least stop it from crashing the program but the exception is still being thrown when no picture is selected in the fdialogbox.

DialogResult result = fileDialog.ShowDialog();
if (result == DialogResult.OK) {
//returns a string for the directory
return fDialog.FileName;
}
return null; //not sure what you will return if they cancel
also, FileName is already a string, so no need to use .ToString() on it
EDIT: fixed indenting

Check the dialog result and act accordingly:
private string ChoosePicture()
{
fDialog.Title = "Select Picture";
fDialog.Filter = "Image Files (*.bmp, *.gif, *.jpg)|*.bmp; *.gif*;*.jpg";
fDialog.InitialDirectory = "C:";
DialogResult res = fDialog.ShowDialog();
if(res == DialogResult.OK)
{
fDialog.AddExtension = true;
fDialog.CheckFileExists = true;
fDialog.CheckPathExists = true;
//returns a string for the directory
return fDialog.FileName.ToString();
}
else
{
return null; // or something
}
}

Test to see if a file was selected:
fDialog.ShowDialog();
if (!string.IsNullOrEmpty(fDialog.FileName))
{
fDialog.AddExtension = true;
fDialog.CheckFileExists = true;
fDialog.CheckPathExists = true;
//returns a string for the directory
return fDialog.FileName.ToString();
} else {
return String.Empty;
}

DialogResult dresult=fDialog.ShowDialog();
Check if dresult==DialogResult.Ok and only after proceed with file operations.

fDialog.AddExtension = true;
fDialog.CheckFileExists = true;
fDialog.CheckPathExists = true;
DialogResult res = fDialog.ShowDialog();
if (res == DialogResult.OK)
{
//returns a string for the directory
return fDialog.FileName.ToString();
}
return null;
Now it will work !
We should add properties to the dialogbox before its actually been shown. So when it opens, it will have all these properties when you open them for the first time.
Edit :okay you have added to the designer by the toolbox already and its by default all of these options. but if some add from code. it should be always before its being shown. I will leave this here. so that someone who does this
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
in code, will know that they should do these property addition before showing the dialog. Again, these true values are by default so unless u have mentioned false before elsewhere and making it true here.

You can just do it like this instead of return fDialog.FileName; and DialogResult.Cancel is a better option since your looking for a cancel and not for the OK result.
DialogResult result = fDialog.ShowDialog();
if (result == DialogResult.Cancel)
{
return;
}

i added a boolean and check if file selected or not
public Form1()
{
InitializeComponent();
}
bool fileSelected = false; //default false because nothing selected at start.
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
openFile();
if (fileSelected == true)
{
codes...
}
}
string path= "";
private void openFile()
{
OpenFileDialog file= new OpenFileDialog();
file.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
file.Filter = "Text File|*.txt";
//file.RestoreDirectory = true;
if (file.ShowDialog() == DialogResult.OK)
{
path= dosya.FileName;
fileSelected = true;
}
else
{
MessageBox.Show("File not selected.");
}
}
i prevent this error like that.

Related

C# Button with DialogResult Retry

I'm going to use two buttons that have a DialogResult Retry. When you push the button the winform will hide, do something and it pops-up again. I use the While method for this. But if you have two buttons with a retry this won't work unless you set one button DialogResult to Yes and do a While method. But is there a better way to do this, case switch or something?
Note this is within a Class
try
{
// Create a form to select objects.
DialogResult result = System.Windows.Forms.DialogResult.None;
while (result == DialogResult.None || result == DialogResult.Retry)
{
// Picking Objects.
if (result == DialogResult.Retry)
{
System.Windows.Forms.SaveFileDialog saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
saveFileDialog1.InitialDirectory = Convert.ToString(Environment.SpecialFolder.MyDocuments);
saveFileDialog1.FileName = "test";
saveFileDialog1.Filter = "Family Files (*.rfa)|*.rfa|All Files (*.*)|*.*";
saveFileDialog1.FilterIndex = 1;
var dialogResult = saveFileDialog1.ShowDialog();
if (dialogResult == DialogResult.OK)
{
string address = "http://www.autodesk.com/revit-basic-sample-family-2017-enu?_ga=2.28765692.1750602280.1538397390-459409917.1521646598";
System.Net.WebClient webClient = new System.Net.WebClient();
webClient.DownloadFile(address, saveFileDialog1.FileName);
Autodesk.Revit.DB.Family family = null;
using (Transaction tx = new Transaction(doc))
{
tx.Start("Load Family");
if (doc.LoadFamily(saveFileDialog1.FileName, out family))
{
String name = family.Name;
TaskDialog.Show("Revit", "Family file " + name + " has been loaded ");
}
else
{
TaskDialog.Show("Revit", "Can't load the family file or already exists.");
}
tx.Commit();
}
}
if (dialogResult == DialogResult.Cancel)
{
}
}
// Show the dialog.
using (testForm selectionForm = new vuurenForm(commandData))
{
result = selectionForm.ShowDialog();
}
}
return Result.Succeeded;
You may set the DialogResult in the code, not in the form designer. Just double click the buttons and add something like:
private void button1_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Retry;
}
That way both buttons will have the same DialogResult.
Than the loop is OK with only checking for the DialogResult.Retry.
Exactly you can try this code to manage your DialogResult like:
switch(MessageBox.Show("Text", "Title", MessageBoxButtons.YesNo))
{
case DailogResult == DialogResult.Yes:
//Do something
case DailogResult == DialogResult.Retry:
//Do something
}
Actually for two Button objects you have to have two event-handler objects and you can set:
DialogResult = DialogResult.Retry;
In the event that you want to Retry.
You can try this:
var dialogResult = DialogResult.Retry;
while (dialogResult == DialogResult.Retry) {
try {
CheckSomething();
break;
}
catch {
if (dialogResult == DialogResult.Abort) {secondDialog.DialogResult = Retry;}
throw;
}
}
You can also use enums like below:
enum Result {Ignore, Abort,Retry};

C# Winform Retry

I have a problem with a Retry form. With this Form, I'm able to load a file from the internet. When it's done the main form pops up again. So far so good.
But when the user presses cancel, the save dialog pops up again. But what I want when the user presses the cancel button, he returns to the main form.
It Should be in this part, I think:
if (saveFileDialog1.ShowDialog() == DialogResult.Cancel)
{
return Result.Cancelled;
}
This is a part of my code:
try
{
// Create a form to select objects.
DialogResult result = System.Windows.Forms.DialogResult.None;
while (result == DialogResult.None || result == DialogResult.Retry)
{
// Picking Objects.
if (result == DialogResult.Retry)
{
System.Windows.Forms.SaveFileDialog saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
saveFileDialog1.InitialDirectory = Convert.ToString(Environment.SpecialFolder.MyDocuments);
saveFileDialog1.FileName = "test";
saveFileDialog1.Filter = "Family Files (*.rfa)|*.rfa|All Files (*.*)|*.*";
saveFileDialog1.FilterIndex = 1;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string address = "http://www.autodesk.com/revit-basic-sample-family-2017-enu?_ga=2.28765692.1750602280.1538397390-459409917.1521646598";
System.Net.WebClient webClient = new System.Net.WebClient();
webClient.DownloadFile(address, saveFileDialog1.FileName);
}
Autodesk.Revit.DB.Family family = null;
using (Transaction tx = new Transaction(doc))
{
tx.Start("Load Family");
if (doc.LoadFamily(saveFileDialog1.FileName, out family))
{
String name = family.Name;
TaskDialog.Show("Revit", "Family file " + name + " has been loaded " );
}
else
{
TaskDialog.Show("Revit", "Can't load the family file or already exists.");
}
tx.Commit();
}
if (saveFileDialog1.ShowDialog() == DialogResult.Cancel)
{
return Result.Cancelled;
}
}
// Show the dialog.
using (pickForm selectionForm = new pickForm(commandData))
{
result = selectionForm.ShowDialog();
}
}
return Result.Succeeded;
Everytime you call saveFileDialog1.ShowDialog() the dialog is opened. You need to store the result of the call for later checks:
if (result == DialogResult.Retry)
{
System.Windows.Forms.SaveFileDialog saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
saveFileDialog1.InitialDirectory = Convert.ToString(Environment.SpecialFolder.MyDocuments);
saveFileDialog1.FileName = "test";
saveFileDialog1.Filter = "Family Files (*.rfa)|*.rfa|All Files (*.*)|*.*";
saveFileDialog1.FilterIndex = 1;
// store result of the dialog
var dialogResult = saveFileDialog1.ShowDialog();
if (dialogResult == DialogResult.OK)
{
// ...
}
// ...
// compare the result without opening the dialog again.
if (dialogResult == DialogResult.Cancel)
{
return Result.Cancelled;
}
I think you can easily use if ... else statement for this like below :
System.Windows.Forms.SaveFileDialog saveFileDialog1 = new SaveFileDialog();
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
// your code
}
else // For Cancel
{
return Result.Cancelled;
}

what can i do to make my code to work

i have 4 errors and im working on my save button if i could get these fixed it will only save the selected items that the user wants
THIS IS NOT all the code just the code that im having problems with. this program is for and icecream application with 2 combo boxes and 3 check boxes
I PUTT COMMENT LINES WHERE I HAVE THE ERRORS ARE AT
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
if (sfd.ShowDialog() == DialogResult.OK)
{
StreamWriter sw = new StreamWriter(
new FileStream(sfd.FileName,
FileMode.Create,
FileAccess.Write)
);
if(flavorBox) // i have an error right here (Cannot implicitly convert type 'System.Windows.Forms.ComboBox' to 'boolean)
{
sw.WriteLine(flavorBox.SelectedItem);
}
else(syrupBox) //syays i need semecolons right here for some reason
{
sw.WriteLine(syrupBox.SelectedItem);
}
if (Nuts.Checked)
{
this.Tag = "checked";
sw.WriteLine(Nuts);
}
else(Cherries.Checked) //says i need semicolons here to i dont know why
{
this.Tag = "checked";
sw.WriteLine(Cherries);
}
if(Sprinkles.Checked)
{
this.Tag = "checked";
sw.WriteLine(Sprinkles);
}
sw.Close();
}
}
THIS IS MY 4TH ERROR
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
DialogResult result = MessageBox.Show("Are you sure you want to send the data back?",
"Data Sender",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
if (result == DialogResult.No)
{
e.Cancel() = true; //ITS ASKED ME AM I MISSING A DIRECTIVE OR ASSEMBLY REFRENCE (FOR CANCEL)
}
In an if-else only the if should have a condition, and the else should not. Use an else if statement to explicitly define a condition.
if (Nuts.Checked)
{
this.Tag = "checked";
sw.WriteLine(Nuts);
}
else if(Cherries.Checked)
{
this.Tag = "checked";
sw.WriteLine(Cherries);
}
else if(Sprinkles.Checked)
{
this.Tag = "checked";
sw.WriteLine(Sprinkles);
}
Flavorbox is a textbox, so by doing if(flavorbox) you are checking if flavorbox is equal to true or false. It's a textbox so this isn't possible. You'll probably have to just change the flavorbox. Try the following:
if(!String.IsNullOrEmpty(flavorbox.Text)) {
sw.WriteLine(flavorBox.SelectedItem);
}
1. about
if(flavorBox)
what are you checking?
about the:
else(syrupBox) and else(Cherries.Checked)
you cannot do else(something).
you can do else if(something)
because else is all the rest of the options.
so change them to:
else if(syrupBox) and else if(Cherries.Checked)
2. about the cancel:
what are you trying to do?
when you click no in the dialog, what are you trying to accomplish with the e.cancel?
For the fourth error, note that EventArgs.Cancel is a property, not a method. Remove the brackets:
e.Cancel = true;

Keep the last selected path using OpenFileDialog / C# / .Net

I want to keep the last path which is selected. This is the code:
private void testFileButton_Click(object sender, EventArgs e)
{
fd = new OpenFileDialog();
fd.FileName = testParameters.testFileFile;
fd.InitialDirectory = testParameters.testFileDir;
if (fd.ShowDialog() == DialogResult.OK)
{
try
{
if (fd.SafeFileName != null)
{
testParameters.testFileDir = Path.GetDirectoryName(fd.FileName);
testParameters.testFileFile = Path.GetFileName(fd.FileName);
testFileLabel.Text = fd.FileName;
}
}
catch (IOException)
{
MessageBox.Show("Error: Could not read file");
}
}
}
to be able to keep the last selected path, I tried to add RestorDirectory and index but I did not get any result:
private void testFileButton_Click(object sender, EventArgs e)
{
fd = new OpenFileDialog();
fd.FileName = testParameters.testFileFile;
fd.InitialDirectory = testParameters.testFileDir;
fd.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
fd.FilterIndex = 2;
fd.RestoreDirectory = true;
if(...){
...
}
}
then I tried to use "else" instead:
private void testFileButton_Click(object sender, EventArgs e)
{
fd = new OpenFileDialog();
fd.FileName = testParameters.testFileFile;
fd.InitialDirectory = testParameters.testFileDir;
if (fd.ShowDialog() == DialogResult.OK)
{
try
{
if (fd.SafeFileName != null)
{
testParameters.testFileDir = Path.GetDirectoryName(fd.FileName);
testParameters.testFileFile = Path.GetFileName(fd.FileName);
testFileLabel.Text = fd.FileName;
}
}
}
catch (IOException)
{
MessageBox.Show("Error: Could not read file");
}
}
else
{
openFileDialog1.InitialDirectory = #"C:\";
}
}
but again without any result..
Does anyone have any idea?
Editing: Last attemp
private void testFileButton_Click(object sender, EventArgs e)
{
//http://stackoverflow.com/questions/7793158/obtaining-only-the-filename-when-using-openfiledialog-property-filename
OpenFileDialog fd = new OpenFileDialog();
fd.FileName = testParameters.testFileFile;
Environment.CurrentDirectory = #"C:\" ;
if (fd.ShowDialog() == DialogResult.OK )
{
try
{
if (fd.SafeFileName != null)
{
string ffileName = fd.FileName;
testParameters.testFileDir = Path.GetDirectoryName(ffileName);
testParameters.testFileFile = Path.GetFileName(ffileName);
testFileLabel.Text = ffileName;
}
}
catch (IOException)
{
MessageBox.Show("Error: Could not read file");
}
}
}
The documentation states:
true if the dialog box restores the current directory to its original value if
the user changed the directory while searching for files; otherwise, false.
Update: Changing my answer a little, since I think I may have misunderstood your intention:
If I'm not mistaken, your dialog will open to fd.InitialDirectory each time you open it, since that is per definition the default for a new instance of fd. I believe this might be your problem here: You are calling fd = new OpenFileDialog(); each time you are trying to open it.
If you change your code to use the same instance for fd each time (define it in an outer scope, and e.g. access a singleton instance via a Property?), it might remember it's previous directory itself - that is the default behavior (which you can override using the RestoreDirectory property).
Example of getting a singleton instance: This will only instantiate the dialog once, and return the same instance each time you call the property:
Private OpenFileDialog _fd;
private OpenFileDialog SingleFd {
get { return _fd ?? (_fd = new OpenFileDialog()); }
}
// Now in your method, use:
var singleInstance = SingleFd;
You are not using same variable for file dialog everywhere. Like in if block you are showing file dialog fd, but in else part you are using variable openFileDialog. I couldn't understand why you are doing this, or probably it is a typo. Use same variable at both place if you want to set initial directory to "C:\" if user cancels the dialog.
Instead of creating instance in every call, create an instance once and use it for subsequent calls.
Regarding directory restore, if we don't set initial directory, by default it restores the previous directory, even for the different instances.
OpenFileDialog initially uses the current directory which is a process-wide setting. You have overridden this behavior by setting the InitialDirectory. Just don't do that and it will work.
If you want to persist the last directory used across process restarts, capture Environment.CurrentDirectory and save it. Set it before opening the dialog.
Note, that the current directory is a process-wide setting so that different parts of the app can interfere. Also, all relative paths are interpreted relative to this directory (which is why relative path are usually a bug waiting).
string path = #"C:\";
OpenFileDialog fd = new OpenFileDialog();
fd.FileName = "SelectFolder";
fd.InitialDirectory =path;
fd.ValidateNames = false;
fd.CheckFileExists = false;
if (fd.ShowDialog() == DialogResult.OK)
{
try
{
if (fd.SafeFileName != null)
{
string txt1 = System.IO.Path.GetFullPath(fd.FileName),
txt2 = txt1.Replace("SelectFolder", "").Trim();
testFileLabel.Text = txt2.Replace(path, "").Replace(#"\", ""); ;
}
}
catch (IOException)
{
MessageBox.Show("Error: Could not read file");
}
}
The Solution is to set the InitialDirectory path Blank
openFileDialog.InitialDirectory = ""
openFileDialog.RestoreDirectory = True

WPF Save DialogBox (for windows 64)

This is similar to older posts on this site but I keep getting an error message. I want to create a button in C # WPF that opens a dialogbox and saves a text file to be read at a later date. This code works for windows 32, but crashes on windows 64. How can I change this code to get it to work on both systems? I am a beginner at programming.
Microsoft.Win32.SaveFileDialog saveFile = new Microsoft.Win32.SaveFileDialog(); //throws error message here
private void savebutton_Click(object sender, RoutedEventArgs e)
{
saveFile.FileName = Class1.stringjobnum;
saveFile.Filter = "CCurtain (*.cur)|*.cur";
saveFile.FilterIndex = 2;
saveFile.InitialDirectory = "T:\\Tank Baffle Curtain Calculator\\SavedTanks";
saveFile.OverwritePrompt = true;
bool? result = saveFile.ShowDialog();
if (result.HasValue && result.Value)
{
clsSaveFile.s_FilePath = saveFile.FileName;
int iDotLoc = clsSaveFile.s_FilePath.LastIndexOf('.');
string strExtTest = clsSaveFile.s_FilePath.Substring(iDotLoc);
if (strExtTest != ".cur")
clsSaveFile.s_FilePath += ".cur";
FileInfo sourceFile = new FileInfo(clsSaveFile.s_FilePath);
clsSaveFile.saveFile();
}
}
You're setting an invalid FilterIndex, that might have something to do with it.
There is no 2nd filter in the filter string as written:
"CCurtain (*.cur)|*.cur"
Try setting the FilterIndex to 1 or adding another filter to the string.
You should try adding a catch around the statement to get a better idea as to what is going on.
try
{
code here
}
catch (Exception ex)
{
ex.message contains the info
}
Also, check for null:
bool? result = saveFile.ShowDialog();
if (result != null && (result.HasValue && result.Value))
{
// code
}
I would create the dialogbox IN the event. And you don't have two different filters.
private void savebutton_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.SaveFileDialog saveFile = new Microsoft.Win32.SaveFileDialog();
saveFile.FileName = Class1.stringjobnum;
saveFile.Filter = "CCurtain|*.cur";;
saveFile.FilterIndex = 1;
saveFile.InitialDirectory = "T:\\Tank Baffle Curtain Calculator\\SavedTanks";
saveFile.OverwritePrompt = true;
// Show open file dialog box
Nullable<bool> result = saveFile.ShowDialog();
// Process open file dialog box results
if (result == true)
{
string filename = saveFile.FileName;
// are you sure you need to check the extension.
// if so extension is a a fileinfo property
}

Categories