System.Windows.Forms.SaveFileDialog不强制执行默认扩展

我正在尝试使SaveFileDialogFileOpenDialog强制扩展用户输入的文件名。 我尝试过使用问题389070中提出的样本,但它没有按预期工作:

 var dialog = new SaveFileDialog()) dialog.AddExtension = true; dialog.DefaultExt = "foo"; dialog.Filter = "Foo Document (*.foo)|*.foo"; if (dialog.ShowDialog() == DialogResult.OK) { ... } 

如果用户在文件test.xml恰好存在的文件夹中键入文本test ,则对话框将建议名称test.xml (而我真的只想在列表中看到*.foo )。 更糟糕的是:如果用户选择了test.xml ,那么我确实会将test.xml作为输出文件名。

如何确保SaveFileDialog真的只允许用户选择*.foo文件? 或者至少,当用户点击“ Save时,它会替换/添加扩展名?

建议的解决方案(实现FileOk事件处理程序)只执行部分工作,因为如果文件名具有错误的扩展名,我真的想要禁用“ Save按钮。

若要保留在对话框中更新FileOk处理程序中文本框中显示的文件名,以反映具有正确扩展名的新文件名,请参阅以下相关问题 。

AFAIK没有可靠的方法来强制执行给定的文件扩展名。 无论如何,一旦对话框关闭,validation正确的扩展名是一个好的做法,如果扩展名不匹配,则通知用户他选择了无效的文件。

您可以处理FileOk事件,如果它不是正确的扩展名,则取消它

 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; } } 

我最接近的是使用FileOk事件。 例如:

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

在MSDN上结帐FileOK事件 。

我遇到了同样的问题,我能够通过执行以下操作来控制显示的内容:

使用OpenFileDialog,过滤字符串中的第一项是默认值

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

使用SaveFileDialog,filter中的第二项用作默认值:

 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(); } } 

将这两个filter与相应的fileDialogs一起使用后,最终会出现预期的结果。 默认情况下,当用户选择保存按钮并显示savefiledialog时,所选的文件类型是savefiledialogfilter中定义的Program X文件类型。 同样,openfiledialog的选定文件类型是openfileDialogfilter中定义的Program X Files Type的文件类型。

如上所述在此线程中进行一些输入validation也是很好的。 我只想指出两个对话框之间的filter似乎不同,即使它们都inheritance了filedialog类。

  //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 } }