System.Windows.Forms.SaveFileDialog does not enforce default extension
Asked Answered
S

5

9

I am trying to make SaveFileDialog and FileOpenDialog enforce an extension to the file name entered by the user. I've tried using the sample proposed in question 389070 but it does not work as intended:

var dialog = new SaveFileDialog())

dialog.AddExtension = true;
dialog.DefaultExt = "foo";
dialog.Filter = "Foo Document (*.foo)|*.foo";

if (dialog.ShowDialog() == DialogResult.OK)
{
    ...
}

If the user types the text test in a folder where a file test.xml happens to exist, the dialog will suggest the name test.xml (whereas I really only want to see *.foo in the list). Worse: if the user selects test.xml, then I will indeed get test.xml as the output file name.

How can I make sure that SaveFileDialog really only allows the user to select a *.foo file? Or at least, that it replaces/adds the extension when the user clicks Save?

The suggested solutions (implement the FileOk event handler) only do part of the job, as I really would like to disable the Save button if the file name has the wrong extension.

In order to stay in the dialog and update the file name displayed in the text box in the FileOk handler, to reflect the new file name with the right extension, see the following related question.

Sequoia answered 21/10, 2009 at 6:23 Comment(2)
I'm not sure, but you could try setting multipleDottedExtensions to True, maybe this does change that behaviour.Ohaus
Nope, this changes nothing at all; but thanks for the hint.Sequoia
G
4

AFAIK there's no reliable way to enforce a given file extension. It is a good practice anyway to verify the correct extension, once the dialog is closed and inform the user that he selected an invalid file if the extension doesn't match.

Galilee answered 21/10, 2009 at 6:36 Comment(0)
T
17

You can handle the FileOk event, and cancel it if it's not the correct extension

private saveFileDialog_FileOk(object sender, CancelEventArgs e)
{
    if (!saveFileDialog.FileName.EndsWith(".foo"))
    {
        MessageBox.Show("Please select a filename with the '.foo' extension");
        e.Cancel = true;
    }
}
Tip answered 2/11, 2009 at 14:23 Comment(0)
G
4

AFAIK there's no reliable way to enforce a given file extension. It is a good practice anyway to verify the correct extension, once the dialog is closed and inform the user that he selected an invalid file if the extension doesn't match.

Galilee answered 21/10, 2009 at 6:36 Comment(0)
H
0

The nearest I've got to this is by using the FileOk event. For example:

dialog.FileOk += openFileDialog1_FileOk;

private void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
{
  if(!dialog.FileName.EndsWith(".foo"))
  { 
     e.Cancel = true;
  }
}

Checkout FileOK Event on MSDN.

Holleran answered 2/11, 2009 at 14:26 Comment(0)
E
0

I ran into this same issue, and I was able to control what was shown by doing the following:

with the OpenFileDialog, the first item in the filter string was the default

openFileDialog1.Filter = "Program x Files (*.pxf)|*.pxf|txt files (*.txt)|*.txt";
openFileDialog1.ShowDialog();

with the SaveFileDialog, the second item in the filter was used as the default:

SaveFileDialog saveFileDialog1 = new SaveFileDialog();

saveFileDialog1.Filter = "txt files (*.txt)|*.txt|Program x Files (*.pxf)|*.pxf";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;

if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
    if (saveFileDialog1.FileName != null)
    {
        // User has typed in a filename and did not click cancel
        saveFile = saveFileDialog1.FileName;
        MessageBox.Show(saveFile);
        saveCurrentState();

    }
} 

After having used these two filters with the respective fileDialogs, The expected results finally occurred. By default, when the user selects the save button and the savefiledialog shows up, the selected filetype is that of the Program X files type defined in the filter for the savefiledialog. Likewise the selected filetype for the openfiledialog is that of the Program X Files Type defined in the filter for the openfileDialog.

It would also be good to do some input validation as mentioned above in this thread. I just wanted to point out that the filters seem to be different between the two dialogs even though they both inherit the filedialog class.

Evelyne answered 19/2, 2012 at 4:55 Comment(1)
No, sorry, you did not properly understand my problem: with your example code for SaveFileDialog, nothing prevents the user of typing foo and having Windows suggest the file name foo.xml if there happens to be an XML file with that name in the open folder. You cannot, currently, make sure that the file name chosen respects the selected *.pfx extension (in your case).Sequoia
E
-1
    //this must be ran as administrator due to the change of a registry key, but it does work...

    private void doWork()
    {
        const string lm = "HKEY_LOCAL_MACHINE";
        const string subkey = "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoComplete";
        const string keyName = lm + subkey;

        int result = (int)Microsoft.Win32.Registry.GetValue(keyName, "AutoComplete In File Dialog", -1);

        MessageBox.Show(result.ToString());

        if(result.ToString() == "-1")
        {
            //-1 means the key does not exist which means we must create one...
            Microsoft.Win32.Registry.SetValue(keyName, "AutoComplete In File Dialog", 0);
            OpenFileDialog ofd1 = new OpenFileDialog();
            ofd1.ShowDialog();
        }
        if (result == 0)
        {
            //The Registry value is already Created and set to '0' and we dont need to do anything
        }
    }
Evelyne answered 25/2, 2012 at 3:0 Comment(1)
Turning off the autocomplete feature is a bit harsh, isn't it?Sequoia

© 2022 - 2024 — McMap. All rights reserved.