Implementing an OpenFileDialog with sound file preview - c#

I would like to implement an open file dialog or file browser that additionally offers a "Preview" button to play the currently selected sound file (wave format in particular, other formats are not necessary for this application).
I could create my own form with various controls such as a treeview and listbox to show the folders and files, but I think I would be reinventing the wheel, or if nothing else going to a lot of work for something very simple. Do you recommend doing this?
Can I modify (inherit) the existing OpenFileDialog and add the sound-playing button to it somehow?
Is there some free library of custom file pickers that could be utilized? (Provided that the license allows inclusion in a commercial sense.)

Before you get carried away hacking the dialog, consider a simple solution first that leverages the FileOk event. Create a form named, say, frmPreview. Give it a constructor that takes a string. You'll need a Cancel and an OK button and code to play the file.
Display that form like this:
var dlg = new OpenFileDialog();
// Set other dlg properties...
dlg.FileOk += (s, cancel) => {
using (var prev = new frmPreview(dlg.FileName)) {
if (prev.ShowDialog() != DialogResult.OK) cancel.Cancel = true;
}
};
if (dlg.ShowDialog(this) == DialogResult.OK) {
// use the file
//...
}
Now, whenever the user clicks Open, your preview form shows up. The user can click Cancel and pick another file from the dialog.

Found this question whilst searching before asking my own. Possible slight simplification of Hans' answer is to use a standard Message Box rather than having to write your own form. Still a popup on a popup though.
private void btnSelect_Click(object sender, RoutedEventArgs e) {
var dlg = new Microsoft.Win32.OpenFileDialog {
DefaultExt = ".csv",
Filter = "Wav Files Only (*.wav)|*.wav",
InitialDirectory = "C:\\Windows\\Media\\",
CheckFileExists = true
};
dlg.FileName = "preselect the existing file if you wish";
dlg.FileOk += (s, cancel) => {
var player = new MediaPlayer();
player.Open(new Uri(dlg.FileName));
player.Play();
var msgres = MessageBox.Show(Path.GetFileName(dlg.FileName)+"\nUse this sound?", "Sound Playing", MessageBoxButton.YesNo);
if (msgres != MessageBoxResult.Yes) cancel.Cancel = true;
player.Stop(); //in case it is a long sound
};
var result = dlg.ShowDialog();
if (result != true) return;
//do whatever with dlg.FileName ...
}
Using a MessageBox provides a clean standard interface

Regarding point 2, I had thought the OpenFileDialog (or SaveFileDialog) weren't extendable in any way - they are provided by the OS.
But, it turns out they could be:
http://www.codeproject.com/KB/dialog/WPFCustomFileDialog.aspx
http://www.codeproject.com/KB/dialog/CustomizeFileDialog.aspx
The first one looks like what you're wanting to achieve.
Good luck.

Related

My Music Player showing multiple instances of the same form, for each track

I am trying to create a simple media player that just runs from the notifyIcon tray using a context menu strip, sitting on an hidden form.
When I click on the menu item 'play mp3's' it opens up a folder, allowing me to select a bunch of mp3 tracks. These tracks are stored in a listbox on the hidden form allowing me to manipulate them through the C# code. The code I have will always play the first song, no problem, but the ones after that has been a pain.
The way I found to make the songs continue to play was by using ShowDialog for each song, but as you guessed that means there are multiple instances of the same form. Soon as I stop using the show.dialog, I am back to one song again. Is it because I am using the WMPLib without the actual player on the form, I am sure that is not the case. I have managed to pick up tons of knowledge on here to get me this far, like using PlayStateChange, being able to select the next Item in the list box and how to play a song list. Unfortunately most of the time this is with using the media player console and buttons.
Here is the specific code that is causing the issue, as it stands it plays every track, soon as I comment out showdialog, it only plays the first song.
private void trackplayer()
{
listBox1.SelectedIndex = listBox1.SelectedIndex + 1;
var selectedUrl = listBox1.SelectedItem.ToString();
player.URL = selectedUrl;
player.controls.play();
mytempFormOpen();
}
public void mytempFormOpen()
{
var myform1 = new Form1();
myform1.ShowDialog();
}
Could you please help a frustrated newbie, any questions I am happy to respond to.
Here is my FormLoad section
#region check internet when form opens
private void Form1_Load(object sender, EventArgs e)
{
notifyIcon1.Text = (playingToolStripMenuItem.Text);
checkTheInternet();
}
#endregion
Here is the Internet Checker Code called from the loadform
#region Check for Internet Connection Loop
private void checkTheInternet()
{
while (true)
{
bool con = NetworkInterface.GetIsNetworkAvailable();
if (con == false)
{
MessageBox.Show("No Internet Connection!");
playingToolStripMenuItem.Text = "No Internet Connection!";
notifyIcon1.Icon = radio_Off;
notifyIcon1.Visible = true;
return;
}
else
{
return;
}
}
}
#endregion
This is where the file selection starts
region Play MP3 List Automatically
private void mP3ToolStripMenuItem_Click(object sender, EventArgs e)
{
player.PlayStateChange += new WMPLib._WMPOCXEvents_PlayStateChangeEventHandler(player_PlayStateChange);
string[] files, paths;
OpenFileDialog oFD = new OpenFileDialog();
oFD.Multiselect = true;
oFD.Filter = "Music Files |*.mp3;*.wav";
if (oFD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
pauseToolStripMenuItem.Visible = true;
files = oFD.SafeFileNames;
for (int i = 0; i < files.Length; i++)
{
listBox1.Items.Add(paths[i]);
myCount = i + 1;
}
trackplayer();
}
}
If opening a new form is needed to play your song, I am not sure why since I do not have all your code, but you do not want multiple forms then do this. Create a private field which will hold a reference to your form:
private Form1 prevForm;
Change your myTempFormOpen to:
public void mytempFormOpen()
{
if (prevForm != null)
{
prevForm.Close();
}
prevForm = new Form1();
prevForm.ShowDialog();
}
Also myTempFormOpen should be MyTempFormOpen to follow .NET naming conventions.
Also in checkInternet method, you can return right away if connection is true instead of checking false first. Also, not sure why you need the while loop.
Let me know if that solves your issue.
I eventually found the answer by using a timer. The answer to the solution can be found here How to detect when a mp3 file has finished playing Big Thanks to all those that helped.

SaveFileDialog's ShowDialog sometimes does not show the form, though it's not closable

I have a common dialog opened like this:
private void SaveLogButton_Click(object sender, EventArgs e)
{
try
{
SaveFileDialog dialog = new SaveFileDialog
{
Filter = #"Text file|*.txt",
Title = #"Save to...",
};
if (dialog.ShowDialog()== DialogResult.OK)
{
// Do some job
}
}
catch (Exception ex)
{
// Handle some errors
}
}
Sometimes, however, (with like 10% probability) ShowDialog() method does not show the dialog itself, though I can see it's parent form, which i can't click too (error sound appears). The only thing that helps here is CtrlAltDel.
No exceptions trigger, and debug wont go after ShowDialog line. Any suggestions?
Thank you.
Short addition: I'm working on an Excel Add-In using WinForms.
Use this 'ShowDialog' overload https://msdn.microsoft.com/en-us/library/9a55b9ds(v=vs.110).aspx to specify Owner.
if (dialog.ShowDialog(this)== DialogResult.OK)

How do I "do something" when a SaveFileDialog is cancelled?

NB: The answer in this question is out of date.
So, I have a save dialog box:
...
SaveFileDialog sfd = new SaveFileDialog();
sfd.ShowDialog();
// SaveFileDialog.[Whatever] - Init code basically.
if (sfd.DialogResult == DialogResult.OK)
{
// Definitely do something.
Console.Print("File selected.");
}
if (sfd.DialogResult == DialogResult.Abort)
{
// Maybe the opposite of the above?
Console.Print("File selection Cancelled");
}
if ( ... ) { }
and so on.
But... SaveFileDialog.DialogResult has been replaced by events instead...
And that the only available events are SaveFileDialog.FileOK, SaveFileDialog.Disposed and SaveFileDialog.HelpRequest.
How do I trigger an event (or move to a line of code) based when the user clicked Cancel rather than completing it (Clicking Save)?
I'm looking to branch based on whether the user cancels or successfully selects the file location to save to.
Working with DialogResult is not deprecated and also those events are not something new.
To perform an action for Cancel, you can create your SaveFileDialog and configure it, you can call ShowDialog and then check the result:
var sfd= new SaveFileDialog();
//Other initializations ...
//sfd.Filter= "Text files (*.txt)|*.txt|All files (*.*)|*.*";
//sfd.DefaultExt = "txt";
if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
MessageBox.Show("Save Clicked");
//ِDo something for save
}
else
{
MessageBox.Show("Cancel Clicked");
//Do something for cancel
}
You can access to selected file using FileName property, for example MessageBox.Show(sfd.FileName);

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.

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