Monday, August 3, 2009

The woes of file extensions in the SaveFileDialog

I stumbled upon a rather annoying problem in the SaveFileDialog (System.Win32) in one of my WPF applications. The application allows saving of its own type of project file with a custom extension ".mypi" and of course loading those files again.

The code for saving:
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "MY Project|*.mypi";

and for loading

OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "MY Projects|*.mypi";

Now some users were complaining about "lost files" that they "could not open", and after a bit of digging around I found that they entered file names in the form of "Project.2009.07.07" in the SaveFileDialog. Now what I would have expected is that the dialog would append the only available extension "mypi", but as the documentation correctly states for the "AddExtension" property (which is set to "true" by default):
Gets or sets a value indicating whether a file dialog automatically adds an extension to a file name if the user omits an extension.

Now the important part is "if the user omits an extension", and since .07 is a valid extension the dialog will not add anything to "Project.2009.07.07". And thus when trying to open the file again the filter will not pick up on it.

The preferred workaround is to change the file name after the dialog closes, note though that you have to hook the SaveFileDialog.FileOk event to check if the file with the added extension exists, otherwise this check will not work correctly in the file dialog.

Not being able to force the SaveFileDialog to add an extension to every file name entered by the user is a rather poor design decision, as the user will assume that a save dialog which only allows to save a certain kind of file will generate such a file. He is strengthened in that assumption by other applications like Word, MS Paint, etc..., which do not display that behavior but always append the filter extension to the file name.
Thus for every SaveFileDialog the same workaround has to be used and functionality that already is in the SaveFileDialog has to be duplicated (check if file exists, check if filename is too long, etc...) and the appropriate error messages localized.

In conclusion the SaveFileDialog should be extended in future versions to allow that kind of behavior without any workaround.

Does anyone know of an alternative route to solve that problem or a third party save file dialog (maybe even written in proper XAML for styling and extendibility)?

Submit this story to DotNetKicks