SaveFileDialog surprisingly adds extension to file - c#

When I select file name "image.mgm", dialog System.Windows.Forms.SaveFileDialog surprisingly adds extension .BMP and return "image.mgm.BMP" via property FileName.
It doesn't happen for "image.png".
Several samples:
image.bmp ==> image.bmp
image.png ==> image.png
image.mgm ==> image.mgm.BMP
image.MGM ==> image.MGM
How can I fix the unexpected (for me) behavior?
Source of sample can be found on github: https://github.com/constructor-igor/TechSugar/tree/master/WinForm/FileSaveDialogIssue/FileSaveDialogIssue
UPD:
additional fact: when I add key "HKEY_CLASSES_ROOT.mgm" to registry, "file dialog" stop's to add ".BMP" to .mgm
public Form1()
{
InitializeComponent();
this.saveFileDialog.AddExtension = false;
}
private void btnOpenFile_Click(object sender, EventArgs e)
{
saveFileDialog.Title = #"Save calculated image";
saveFileDialog.FileName = "noname.tiff";
saveFileDialog.Filter = #"My Files(*.BMP;*.MGM;*.PNG)|*.BMP;*.MGM;*.PNG|All files (*.*)|*.*";
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
MessageBox.Show(String.Format("File name {0}", saveFileDialog.FileName));
}
}

You have to use non-capital letters when defining file mask
saveFileDialog.Filter = #"My Files(*.BMP;*.MGM;*.PNG)|*.bmp;*.mgm;*.png|All files (*.*)|*.*";
This will work with either "1.mgm" or "1.MGM"
However, "1.mGm" and "1.MgM" won't work, could be fixed by adding "*.mGm" mask (just this one fixes both cases).
But then you still have problem with "1.Mgm".. sigh.
"*.mgm;*.mGm;*.Mgm;*.mgM;"

Related

OpenFileDialog is not opening the file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have bound the openFileDialog control with button. On button event, I am calling the openFileDialog control.
Now, when I am running my application, the openFileDialog box gets open but does not select the file. The open button is not working.
Example code:
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
}
private void openFileDialog1_FileOk_1(object sender, CancelEventArgs e)
{
// logic written here
}
It was working fine earlier but now its not working.
You need to use the DialogResult to get the event of open confirmation by the user. Then you can use a stream to read the file. Here is some sample code (provided by MS in the MSDN - source:https://msdn.microsoft.com/en-us/library/system.windows.forms.openfiledialog(v=vs.110).aspx):
private void button1_Click(object sender, System.EventArgs e)
{
Stream myStream = null;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = "c:\\" ;
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ;
openFileDialog1.FilterIndex = 2 ;
openFileDialog1.RestoreDirectory = true ;
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
// Some logic here
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Failed to open file. Original error: " + ex.Message);
}
}
}
Answer post edits
The included code shows the method openFileDialog1_FileOk_1 the "_1" at the end suggest to me that you had some issues binding the event. Perhaps there was at some point a method openFileDialog1_FileOk caused conflict.
You should check if the method is correctly bound to the event.
For that I will remit you to my answer to How to change the name of an existing event handler?
For abstract you want to see what method is bound to the event. You can do it from the properties panel, or by checking the form designer file (that is named something .Designer.cs for example: Form1.Designer.cs).
Addendum: Consider adding a break point in the event handler. It will allow you to debug step by step what is happening. Also, it will allow you notice if the event handlers is not being executed at all, which would suggest that the method is NOT correctly bound to the event.
Original Answer
OpenFileDialog Does not open files, it barely select thems and makes the selection available for your application to do whatever your applications is intended to do with those files.
The following is the usage pattern from the MSDN article linked above:
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
// Insert code to read the stream here.
}
}
}
catch (Exception ex)
{
MessageBox.Show
(
"Error: Could not read file from disk. Original error: " + ex.Message
);
}
}
Now, observe that after cheking the result of ShowDialog - which returns once the dialogs is closed - the codes uses the method OpenFile to actually open the file. The result is a stream that you can process anyway you prefer.
Alternatively you can retrieve the selected files via the property FileNames, which returns an array of strings. If you have configured the dialog to only allow selecting asingle file you are ok to use FileName instead.
Addendum, if by "Open" you mean to invoke the default application associated with the selected file to open the file. You can accomplish that by passing the file path to System.Diagnostics.Process.Start.
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string name = openFileDialog1.FileName;
object objOpt = Type.Missing;
var excelApp = new Excel.Application();
Excel.Workbook wbclass = excelApp.Workbooks.Open(name, objOpt,
true,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt);
}

How to copy a file to pre-destinated folder using File.OpenDialog?

Using File.OpenDialog how can i make a copy of selected files to a certain (predeclared or even better from a string variable taken from textbox) location?
I assume i can firstly simply use the ofd method, but where to determine the location to copy?
InitializeComponent();
PopulateTreeView();
this.treeView1.NodeMouseClick +=
new TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseClick);
OpenFileDialog ofd1 = new OpenFileDialog();
and for the button:
private void button3_Click(object sender, EventArgs e)
{
if (ofd1.ShowDialog() == DialogResult.OK)
{ }
}
If I understood correctly, then once you select the file from open file dialog, you want to copy it to a certain location. Then you can use something like this code -
if (this.openFileDialog1.ShowDialog()== System.Windows.Forms.DialogResult.OK)
{
var fileName = this.openFileDialog1.FileName;
File.Copy(fileName, "DestinationFilePath");
}
Or in case of multiple selected file, something like this -
if (this.openFileDialog1.ShowDialog()== System.Windows.Forms.DialogResult.OK)
{
var fileNames = this.openFileDialog1.FileNames;
foreach (var fileName in fileNames)
{
File.Copy(fileName, "DestinationFilePath/" + fileName);
}
}
Check out the foreach loop in this for iterating through all of the files you selected using the OpenDialog.
I think this is what you're looking for in regards to actually copying the files. It takes a source directory and copies to the destination you provide.

How to reference the Paint.NET assemblies directly using C#

I wanted to reference the Paint.NET assemblies directly and use a its functionality that way. i dont know how to use the .dll file PaintDotNet.Core.dll
and use it functionality in C# visual studio any helps. Please
want to reference to these assemblies: C:\Program Files\Paint.NET\PaintDotNet.*.dll Then poke around the classes in those namespaces.
Codes:-
private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
string filename = "";
if (ofd.ShowDialog() == DialogResult.OK)
{
filename = System.IO.Path.GetFullPath(ofd.FileName);
}
// MessageBox.Show(filename, "file");
pictureBox1.ImageLocation = filename;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
DialogResult result = MessageBox.Show("Do you wish to continue?", "Save Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
System.Diagnostics.Process.Start(#"C:\Program Files\Paint.NET\PaintDotNet.exe");
// here i need to perform the function like
//Open + O`
//ctrl + Shift + L)` then `
//(ctrl + Shift + G)`. then save
//`ctrl + Shift + S`
}
else
{
return;
}
}
Just follow the instruction to send the shortcut key to another application
Add this namespace to the class
using System.Runtime.InteropServices;
Then declare SetForegroundWindow function with DllImport statement. this will create object of that method which has been created in User32.dll
[DllImport ("User32.dll")]
static extern int SetForegroundWindow(IntPtr point);
And add the following code to your button click or anywhere in your project. This code will navigate the OpenFileDialog to open the existing file in Paint.NET application.
private void button1_Click(object sender, EventArgs e)
{
Process p = Process.GetProcessesByName("PaintDotNet").FirstOrDefault();
if (p != null)
{
SetForegroundWindow(p.MainWindowHandle); //Set the Paint.NET application at front
SendKeys.SendWait("^(o)"); //^(o) will sends the Ctrl+O key to the application.
}
}
most of programmers made the mistake between Ctrl+O and Ctrl+o seems similar but, the ascii value of both key is different. So, make sure the key character is not in uppercase. You can also read the full information about SendKey method on msdn. You can make any key combination and send through the SendWait() method.
Just add one or some or all of the libraries to your project. as Measuring states then use the object explorer.
NOTE: never mind the .xaml stuff or the actual projects I am trying to render SharpDX D3D11 in a wpf app to make a map editor (and without the toolkit (don't ask me why. I am crazy)).
I swear I have the code last night are you trying to automate paint.net?
you will have to make a plug-in which would make the process way more streamlined than having to start a second app.

How do I keep track of the last folder selected by a user?

I thought using application settings would do the trick but I'm not getting it to work. This is what I have:
private void btnBrowse_Click(object sender, EventArgs e)
{
if (fbFolderBrowser.ShowDialog() == DialogResult.OK)
{
// I want to open the last folder selected by the user here.
}
When the user clicks on this button, I want to open the browse window to the last folder he accessed and save it. Next time he clicks on the button, it'll automatically select that folder.
I was thinking maybe I could use user variables where I can change at run-time but I'm not getting it to work. Can anyone give me a hand?
Go to Settings Page, Project Designer of the project which you have created and add folder path variable inside the application. Now add below code to restore the last selected folder path.
FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
folderBrowser.Description = "Select a folder to extract to:";
folderBrowser.ShowNewFolderButton = true;
folderBrowser.SelectedPath = Properties.Settings.Default.Folder_Path;
//folderBrowser.SelectedPath = project_name.Properties.Settings.Default.Folder_Path;
if (folderBrowser.ShowDialog() == DialogResult.OK)
{
if (!String.IsNullOrEmpty(Properties.Settings.Default.Folder_Path))
Properties.Settings.Default.Folder_Path = folderBrowser.SelectedPath;
Properties.Settings.Default.Folder_Path = folderBrowser.SelectedPath;
Properties.Settings.Default.Save();
}
There are two places where you can find the last folder accessed by a user:
Recent Files and Folders: It can be found here: C:\Documents and Settings\USER\Recent
Registry: In the registry to look here: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU
You can use this snippet to find it:
public static string GetLastOpenSaveFile(string extention)
{
RegistryKey regKey = Registry.CurrentUser;
string lastUsedFolder = string.Empty;
regKey = regKey.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU");
if (string.IsNullOrEmpty(extention))
extention = "html";
RegistryKey myKey = regKey.OpenSubKey(extention);
if (myKey == null && regKey.GetSubKeyNames().Length > 0)
myKey = regKey.OpenSubKey(regKey.GetSubKeyNames()[regKey.GetSubKeyNames().Length - 2]);
if (myKey != null)
{
string[] names = myKey.GetValueNames();
if (names != null && names.Length > 0)
{
lastUsedFolder = (string)myKey.GetValue(names[names.Length - 2]);
}
}
return lastUsedFolder;
}
OR
In windows XP when you press Save on a SaveFileDialog the directory where the file is saved, is set as the new current working directory (the one in Environment.CurrentDirectory).
In this way, when you reopen the FileDialog, it is opened on the same directory as before.
By setting FileDialog.RestoreDirectory = true, when you close the FileDialog the original working directory is restored.
In Windows Vista/Seven the behavior is always as FileDialog.RestoreDirectory = true.
Application settings can do the trick. A more elaborated version is here
use a Setting of type string
create a setting for each button and store the Path there. Then use
the setting as the ofd.InitialPath
using the above code example, try this:
right click your app name in Solution Explorer, click on the Settings
tab Name = Button1Path Type = String Scope = User
then use this:
private void btnBrowse_Click(object sender, EventArgs e)
{
fbFolderBrowser.InitialDirectory=this.Settings.Button1Path;
if (fbFolderBrowser.ShowDialog() == DialogResult.OK)
{
// I want to open the last folder selected by the user here.
this.Settings.Button1Path=fbFolderBrowser.SelectedPath
}
}
You can easily keep track of your last-selected folder, like this:
public String LastSelectedFolder;
private void btnBrowse_Click(object sender, EventArgs e)
{
fbFolderBrowser.InitialDirectory=this.Settings.Button1Path;
if (fbFolderBrowser.ShowDialog() == DialogResult.OK)
{
// Save Last selected folder.
LastSelectedFolder = fbFolderBrowser.SelectedPath;
}
}
I know this is a very old thread, but none of the answers point to the simplest way to re-open the file browser on user's last location.
simply define RestoreDirectory = true.
Check the example
var fd = new OpenFileDialog
{
Filter = #"All Files|*.*",
RestoreDirectory = true,
CheckFileExists = true
};
Class OpenFileDialog api reference
https://msdn.microsoft.com/en-us/library/system.windows.forms.filedialog.restoredirectory(v=vs.110).aspx
Unless I misunderstood the intention of the post, this is by far the simplest way to achieve it. However, if you do need to print this last location, then check the other

System.Windows.Forms.SaveFileDialog does not enforce default extension

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

Categories