2

I'm trying to save a document by using SaveFileDialog. The filter should allow the user to save the document as .doc or .docx, but if the user tpyes as filename 'Test.txt', the file is being saved as Test.txt and not Test.txt.doc

How do I prevent the type conversion of the file and let the user only save .doc or .docx files? If the user doesn't pick one of the 2 extension by himself, it should always save as .doc.

My current code looks like this:

SaveFileDialog sfd = new SaveFileDialog();
string savepath = "";
sfd.Filter = "Wordfile (*.doc;*.docx;)|*.doc;*.docx)";
sfd.DefaultExt = ".doc";
sfd.SupportMultiDottedExtensions = true;
sfd.OverwritePrompt = true;
sfd.AddExtension = true;
sfd.ShowDialog();

//Save the document
doc.SaveAs(sfd.FileName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

I could make an if and ask if sfd.FileName ends with .doc or .docx, but this is kinda complicated and makes the Filter for SaveFileDialog totally useles...

When I type the FileName 'Test', the output would be Test.doc, when I type 'Test.txt', the ouptout would be 'Test.txt'

Edit: Ilyas answer is kinda correct. It works with .txt as extension, but not when I just type 'Test' or 'Test.doc' as filename, because it will always save the file as 'Test.doc.doc'. My current solution:

//.....
sfd.ShowDialog();
if (!sfd.FileName.EndsWith(".doc") && !sfd.FileName.EndsWith(".docx"))
    sfd.FileName += ".doc";

edit: Solution can be found in Ilyas answer or my comment on Ilyas answer.

Rudi
  • 926
  • 2
  • 19
  • 38
  • If you're giving the option to _save as_ then the user should have the ultimate control, as is provided. If you want to control their computer and their files that much then implement to check, but this is arrogant. – Grant Thomas May 29 '13 at 09:08
  • @AlexFilipovici thanks :), but in my eyes it's not really the best way to do If(..EndsWith(".doc") || ...EndsWith(".docx"). It would be a long if when I e.g. save an image and have 10 formats. Anyway, it works. – Rudi May 29 '13 at 09:17
  • @GrantThomas It's perfectly acceptible to force a file to have a specific suffix when using "Save As". Try saving a file from Word and adding ".txt" as a suffix. It'll turn it into "*.txt.docx". – Matthew Watson May 29 '13 at 09:28
  • @MatthewWatson Whoever said MS Office did things the 'right' way? They also give the _any_ option. – Grant Thomas May 29 '13 at 09:29
  • @GrantThomas Word 2010 and later does not have an `any` option - you must choose a specific format. It wouldn't be very good to let the user save a file with a specific format with the wrong suffix because if you double-click it in explorer it'll try to open it with the wrong application. I just used Word as a (common) example. Most other applications which save files in a format with a registered file suffix work the same way, for the same reason. – Matthew Watson May 29 '13 at 09:33
  • @MatthewWatson Because it's _your_ computer and you _just might_ know what you're doing a little better than an app. – Grant Thomas May 29 '13 at 09:36
  • @GrantThomas Indeed, and that's why I know I can just rename it in Windows Explorer if I want. But you don't want to make it easy for your average user to do this; it just causes support issues. And seriously - how often have you wanted to save a ".docx" file with the wrong suffix? For me, that's a big fat "never". – Matthew Watson May 29 '13 at 09:37

1 Answers1

1
var sfd = new SaveFileDialog();
sfd.Filter = "Worddatei (*.doc;*.docx;)|*.doc;*.docx)";

Func<string, bool> isGoodExtension = path => new[]{".doc", ".docx"}.Contains(Path.GetExtension(path));

sfd.FileOk += (s, arg) => sfd.FileName += isGoodExtension(sfd.FileName) ? "" : ".doc";

sfd.ShowDialog();

//Save the document
Console.WriteLine (sfd.FileName);

Prints 1.txt.doc if a enter 1.txt. Feel free to extract logic of checking or appending into another method, so to make code more readable

Ilya Ivanov
  • 23,148
  • 4
  • 64
  • 90
  • `sfd.FileOk += (s, arg) => sfd.FileName += new[] { "doc, docx" }.ToString().Contains(Path.GetExtension(sfd.FileName)) ? "" : ".doc";` is working fine, thanks! – Rudi May 29 '13 at 09:38
  • 1
    Ok, I tried this and it works with the false extension, but not with the right extension. When I type 'Test.txt', it will save the file as 'Test.txt.doc', but when I just type 'Test', it will save the file as 'Test.doc.doc'. sfd.AddExtension is false and DefaultExt is ""... – Rudi May 29 '13 at 10:02
  • @Rudi updated my answer, sorry for mistake – Ilya Ivanov May 29 '13 at 11:57
  • I belive you that it would work, but I'm using .NET Framework 2 and I can't use Func<>. Could you maybe give me another solution like before without the Func<> ? – Rudi May 29 '13 at 12:33
  • 1
    This one is working under .NET Framework 3 or earlier. ` sfd.FileOk += (s, arg) => sfd.FileName += Path.GetExtension(sfd.FileName).Contains(".docx") || Path.GetExtension(sfd.FileName).Contains(".doc") ? "" : ".doc" ; ` Thanks you Ilya :) – Rudi May 29 '13 at 12:55