4

my program has a save file option which is shown below :

        //Browse for file
        SaveFileDialog ofd = new SaveFileDialog();
        ofd.Filter = "CSV|*.csv";
        ofd.DefaultExt = ".csv";

        DialogResult result = ofd.ShowDialog();
        string converted = result.ToString();

        if (converted == "OK")
        {
            Master_Inventory_Export_savePath.Text = ofd.FileName;
        }

if I write the file name as "example" it saves correctly as a .csv however if I set the name as "example.txt" it saves as a text file , I've looked on msdn etc but even setting the default extension doesn't prevent this , any ideas on how to only allow files of .csv to be saved ?

user2678756
  • 61
  • 1
  • 7
  • Few questions. 1st: why the h*** you convert DialogResult to string? 2nd: if user intentionally add an extension...why you have to change it to something else? Would you be happy if Notepad changes your extension to .txt when you're trying to save a HTML file you wrote? – Adriano Repetti Sep 11 '13 at 14:30
  • @Adriano I add the csv extension but i need to perform this check to remove the .txt or other extension so that the system works if the user types in the wrong extension – user2678756 Sep 11 '13 at 14:31
  • _"...if user intentionally adds..."_. I would feel upset if I write A.TXT and Excel will save A.CSV because I selected CSV **format**. That said better to prevent user to specify another extension if you don't want that (at least he won't be surprised to don't find what he asked for). – Adriano Repetti Sep 11 '13 at 14:43
  • 1
    @Adriano I see your point, but on the flip side, i doubt he's writing any sort of multi-purpose program, such as a text editor, but probably something specific that expects certain types of inputs/outputs. – user2366842 Sep 11 '13 at 14:54
  • @user2366842 yes maybe. I thought I wouldn't because CSV is pretty common format and sometimes I wouldn't let it open directly by Excel (because it doesn't conform very well to CSV RFC). – Adriano Repetti Sep 11 '13 at 15:03

3 Answers3

8

You could use the FileOk event to check what your user types and refuse the input if it types something that you don't like.

For example:

SaveFileDialog sdlg = new SaveFileDialog();
sdlg.FileOk += CheckIfFileHasCorrectExtension;
sdlg.Filter = "CSV Files (*.csv)|*.csv";
if(sdlg.ShowDialog() == DialogResult.OK)
    Console.WriteLine("Save file:" + sdlg.FileName);

 void CheckIfFileHasCorrectExtension(object sender, CancelEventArgs e)
 {
     SaveFileDialog sv = (sender as SaveFileDialog);
     if(Path.GetExtension(sv.FileName).ToLower() != ".csv")
     {
         e.Cancel = true;
         MessageBox.Show("Please omit the extension or use 'CSV'");
         return;
     }
 }

The main advantage of this approach is that your SaveFileDialog is not dismissed and you could check the input without reloading the SaveFileDialog if something is wrong.

BEWARE that the SaveFileDialog appends automatically your extension if it doesn't recognize the extension typed by your user. This means that if your user types somefile.doc then the SaveFileDialog doesn't append the .CSV extension because the .DOC extension is probably well known in the OS. But if your user types somefile.zxc then you receive as output (and also in the FileOk event) a FileName called somefile.zxc.csv

Steve
  • 213,761
  • 22
  • 232
  • 286
  • Thank you Steve. I used this method to disallow overwrite (new files only) in VB.net - SaveFileDialog is declared as *private WithEvents* and handler *Handles dialog.FileOk*, set *dialog.OverwritePrompt = False* to suppress the system overwrite message so the dialog jumps straight to a messagebox saying "Overwrite NOT allowed" - just what I was looking for! – Michael Stimson Nov 18 '14 at 23:00
1

can you not just force the .csv filetype by going like so in the last block of code?

if (converted == "OK")
{
    if (ofd.FileName.toString.EndsWith(".csv")<1)
    {
     Master_Inventory_Export_savePath.Text = ofd.FileName + ".csv";
    }
    else
    {
    Master_Inventory_Export_savePath.Text = ofd.FileName;
    }
}

Note - untested, but should give you a starting point....

user2366842
  • 1,231
  • 14
  • 23
  • yeah, this would run into problems with edge cases...Steve's answer is a bit more complete than this, this was just a quick thought. Although I have updated it a little to work around the csv.other scenario. – user2366842 Sep 11 '13 at 14:42
  • Should at least change IndexOf to EndsWith. – bland Sep 12 '13 at 11:33
  • @bland you're correct. Didn't really think this one through entirely, i guess :) Code updated to reflect this. – user2366842 Sep 12 '13 at 14:55
-1

Set the property AddExtension to true.

ofd.AddExtension = true;
orel
  • 1,384
  • 10
  • 12