Where is the proper place to dispose an image - c#

I have a form with OpenFileDialog for selecting image and showing it in pictureBox. Until the form is open the user can open and then save the opened image as many times as he wants. What I want to do is, after each new selection-save, to delete the previously saved image if there is such. The problem is that as I implemented the code now I am able to delete the image the first time, if I keep on saving images with the currently open form I get an error that the resource is being used. What I do is Dispose() the image but I guess I don't do it in the right place.
This is how I open and load the image:
private void btnExplorer_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Title = "Select file";
openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = fileNameFilter;
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;
openFileDialog1.FileName = prefixFilter;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
pictureBox1.InitialImage = new Bitmap(openFileDialog1.FileName);
pictureBox1.ImageLocation = openFileDialog1.FileName;
selectedFile = pictureBox1.ImageLocation;
selectedFileName = openFileDialog1.SafeFileName;
pictureBox1.Load();
}
catch (Exception ex)
{
logger.Error(ex.ToString());
MessageBox.Show("Error loading image!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
And in the same class I have this method which I call if I need to delete an old image:
public void DeleteImage(AppConfig imagePath, string ImageName)
{
pictureBox1.InitialImage.Dispose();//Release the image before trying to delete it
string imgPath = imagePath.ConfigValue.ToString();
File.Delete(imgPath + "\\" + ImageName);
}
As you can see. The Dispose() method is here which I though will ensure that the resource will be disposed before trying to delete it but as I said this only work once and then I get the error as many times as attempts to save image I make.
P.S
The exact error I get is:
The process cannot access the file 'C:\Images\ME_083a210e1a7644198fe1ecaceb80af52.jpg' because it is being used by another process.

There is a better way to do it. Load the image using FileStream and than assign it to the pictureBox
FileStream bmp = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
Image img = new Bitmap(bmp);
pictureBox1.Image = img;
bmp.Close();
and if you want to clear the picture box, simply
pictureBox1.Image = null;

If I understand this correctly you want to remove the once "used" image from it's picture box: Set
picturebox.InitialImage=null;
(By the way: You better use picturebox.Image ...)
"Dispose" is to force the garbage collector to remove an unused object from memory.
Your error has nothing to do with the disposal of the pictureBox-image but with the lock of the source file.
Maybe it already helps if you use a "using" block for the handling of the openFileDialog.

private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Title = "Select file";
openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "Jpeg Files(*.jpg)|*.jpg|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
pictureBox1.InitialImage = new Bitmap(openFileDialog1.FileName);
pictureBox1.ImageLocation = openFileDialog1.FileName;
selectedFile = pictureBox1.ImageLocation;
selectedFileName = openFileDialog1.SafeFileName;
pictureBox1.Load();
}
}
public string selectedFileName { get; set; }
public string selectedFile { get; set; }
private void button2_Click(object sender, EventArgs e)
{
pictureBox1.ImageLocation = null;
}

Related

Open Excel File using OpenFileDialog in C# Windows Form

I am able to choose an Excel file, but after I clicked on Open, the excel file doesn't appear. What should I do? I'm still new with OpenFileDialog, it will be good if anyone can tell what I should add to make the excel file appear after clicking on Open.
Modified from http://www.c-sharpcorner.com/uploadfile/mahesh/openfiledialog-in-c-sharp/
This is my code:
private void BrowseButton_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = #"C:\";
openFileDialog1.Title = "Browse Text Files";
openFileDialog1.CheckFileExists = true;
openFileDialog1.CheckPathExists = true;
openFileDialog1.DefaultExt = "txt";
openFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;
openFileDialog1.ReadOnlyChecked = true;
openFileDialog1.ShowReadOnly = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string file = openFileDialog1.FileName;
try
{
string text = File.ReadAllText(file);
int size = text.Length;
}
catch (IOException)
{
}
}
}
public bool ThumbnailCallback()
{
return false;
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
}
After I clicked Open, only the file name appear, but not the excel file - https://i.stack.imgur.com/GXToy.jpg
You need to set the filter to select excel files.
openFileDialog1.Filter = "Excel Worksheets|*.xls";
You can refer the documentation here.
If you only want to open the Excel file using the default application that is associated to *.xlsx files (which usually is MS Excel when it is installed), then you can simply use the Process.Start(string) method. In you case it may look something like this:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
Process.Start(openFileDialog1.FileName);
}

Trying to get filepath through Openfiledialogue

I am writing code for button click on which using filedialogue the file opens and i am able to choose picture from it. then i want to extract the path of the file and store it in a string variable and pass that as argument ( here compiler throws exception: "A first chance exception of type 'System.IO.FileNotFoundException' occurred in System.Drawing.dll,Additional information: OK" ), as for my code i need the path dynamically so that everytime similar picture doesn't showup ..
//choose image from file
public void select_image_button17_Click(object sender, EventArgs e)
{
foreach (Button b in game_panel1.Controls)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "JPG|*.jpg;*.jpeg|PNG|*.png";
string a = "";
a = openFileDialog1.ShowDialog().ToString();
string directoryPath = Path.GetDirectoryName(a);
Image ToBeCropped = Image.FromFile(a,true);//exception
ReturnCroppedList(ToBeCropped, 320, 320);
pictureBox1.Image = ToBeCropped;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
AddImagesToButtons(images);
}
}
The FileName property will be set when the dialog returns with an OK status.
if (openFileDialog1.ShowDialog() != DialogResult.OK)
{
// User cancelled out of dialog
}
else
{
string filename = openFileDialog1.FileName;
}

Trying to save file without using SaveFileDialog

I am creating a text editor and i am stuck on the SaveFileDialog window opening
and asking to overwrite the current file open.
I have seen all the similar questions asked like this on SO but none have been able to help me. I have even tried the code from this question: "Saving file without dialog" Saving file without dialog
I got stuck on my program having a problem with FileName.
Here is the code i have currently
namespace Text_Editor
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
richTextBox1.Clear();
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
open.Title = "Open File";
open.FileName = "";
if (open.ShowDialog() == DialogResult.OK)
{
this.Text = string.Format("{0}", Path.GetFileNameWithoutExtension(open.FileName));
StreamReader reader = new StreamReader(open.FileName);
richTextBox1.Text = reader.ReadToEnd();
reader.Close();
}
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveFileDialog save = new SaveFileDialog();
save.Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
save.Title = "Save File";
save.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (save.ShowDialog() == DialogResult.OK)
{
StreamWriter writer = new StreamWriter(save.FileName);
writer.Write(richTextBox1.Text);
writer.Close();
}
}
private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveFileDialog saving = new SaveFileDialog();
saving.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
saving.Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
saving.Title = "Save As";
saving.FileName = "Untitled";
if (saving.ShowDialog() == DialogResult.OK)
{
StreamWriter writing = new StreamWriter(saving.FileName);
writing.Write(richTextBox1.Text);
writing.Close();
}
}
}
}
So my question is how can i modify my code so that i can save a file currently open without having the SaveFileDialog box opening everytime?
I do understand that it has something to do with the fact that i'm calling .ShowDialog but i don't know how to modify it.
When opening the file, save the FileName in a form-level variable or property.
Now while saving the file, you can use this FileName instead of getting it from a FileOpenDialog.
First declare a variable to hold filename at form level
// declare at form level
private string FileName = string.Empty;
When opening a file, save the FileName in this variable
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
open.Title = "Open File";
open.FileName = "";
if (open.ShowDialog() == DialogResult.OK)
{
// save the opened FileName in our variable
this.FileName = open.FileName;
this.Text = string.Format("{0}", Path.GetFileNameWithoutExtension(open.FileName));
StreamReader reader = new StreamReader(open.FileName);
richTextBox1.Text = reader.ReadToEnd();
reader.Close();
}
}
And when doing SaveAs operation, update this variable
private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveFileDialog saving = new SaveFileDialog();
saving.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
saving.Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
saving.Title = "Save As";
saving.FileName = "Untitled";
if (saving.ShowDialog() == DialogResult.OK)
{
// save the new FileName in our variable
this.FileName = saving.FileName;
StreamWriter writing = new StreamWriter(saving.FileName);
writing.Write(richTextBox1.Text);
writing.Close();
}
}
The save function can then be modified like this:
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(this.FileName))
{
// call SaveAs
saveAsToolStripMenuItem_Click(sender, e);
} else {
// we already have the filename. we overwrite that file.
StreamWriter writer = new StreamWriter(this.FileName);
writer.Write(richTextBox1.Text);
writer.Close();
}
}
In the New (and Close) function, you should clear this variable
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
// clear the FileName
this.FileName = string.Empty;
richTextBox1.Clear();
}
Create a new string variable in your class for example
string filename = string.empty
and then
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
if(string.IsNullOrEmpty(filename)) {
//Show Save filedialog
SaveFileDialog save = new SaveFileDialog();
save.Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
save.Title = "Save File";
save.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (save.ShowDialog() == DialogResult.OK)
{
filename = save.FileName;
}
}
StreamWriter writer = new StreamWriter(filename);
writer.Write(richTextBox1.Text);
writer.Close();
}
The SaveFileDialog now only opens if fileName is null or empty
You will have to store the fact that you have already saved the file, e.g. by storing the file name in a member variable of the Form class you have. Then use an if to check whether you have already saved your file or not, and then either display the SaveFileDialog using ShowDialog() (in case you haven't) or don't and continue to save to the already defined file name (stored in your member variable).
Give it a try, do the following:
Define a string member variable, call it _fileName (private string _fileName; in your class)
In your saveToolStripMenuItem_Click method, check if it's null (if (null == _fileName))
If it is null, continue as before (show dialog), and after getting the file name, store it in your member variable
Refactor your file writing code so that you either get the file name from the file dialog (like before), or from your member variable _fileName
Have fun, C# is a great language to program in.
First, extract method from saveAsToolStripMenuItem_Click: what if you want add up a popup menu, speed button? Then just implement
public partial class Form1: Form {
// File name to save text to
private String m_FileName = "";
private Boolean SaveText(Boolean showDialog) {
// If file name is not assigned or dialog explictly required
if (String.IsNullOrEmpty(m_FileName) || showDialog) {
// Wrap IDisposable into using
using (SaveFileDialog dlg = new SaveFileDialog()) {
dlg.Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
dlg.Title = "Save File";
dlg.FileName = m_FileName;
if (dlg.ShowDialog() != DialogResult.OK)
return false;
m_FileName = dlg.FileName;
}
}
File.WriteAllText(m_FileName, richTextBox1.Text);
this.Text = Path.GetFileNameWithoutExtension(m_FileName);
return true;
}
private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) {
// SaveAs: always show the dialog
SaveText(true);
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e) {
// Save: show the dialog when required only
SaveText(false);
}
...
}

c# Get File Name

private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog newOpen = new OpenFileDialog();
DialogResult result = newOpen.ShowDialog();
this.textBox1.Text = result + "";
}
It just returns "OK"
What am I doing wrong? I wish to get the PATH to the file and display it in a text box.
The ShowDialog method returns whether the user pressed OK or Cancel. This is useful information, but the actual filename is stored as a property on the dialog
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog newOpen = new OpenFileDialog();
DialogResult result = newOpen.ShowDialog();
if(result == DialogResult.OK) {
this.textBox1.Text = newOpen.FileName;
}
}
You need to access the filename:
string filename = newOpen.FileName;
or filenames, if you allowed multiple file selection:
newOpen.FileNames;
Ref.: OpenFileDialog Class
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)
{
// Insert code to read the stream here.
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file. Error: " + ex.Message);
}
}
}
You need to read the FileName property of the OpenFileDialog instance. This will get you the path of the selected file.
Here is an example of using an existing file as a default, and getting a new file back:
private string open(string oldFile)
{
OpenFileDialog newOpen = new OpenFileDialog();
if (!string.IsNullOrEmpty(oldFile))
{
newOpen.InitialDirectory = Path.GetDirectoryName(oldFile);
newOpen.FileName = Path.GetFileName(oldFile);
}
newOpen.Filter = "eXtensible Markup Language File (*.xml) |*.xml"; //Optional filter
DialogResult result = newOpen.ShowDialog();
if(result == DialogResult.OK) {
return newOpen.FileName;
}
return string.Empty;
}
Path.GetDirectoryName(file) : Return path
Path.GetFileName(file) : Return filename

Load a bitmap image into Windows Forms using open file dialog

I need to open the bitmap image in the window form using open file dialog (I will load it from drive). The image should fit in the picture box.
Here is the code I tried:
private void button1_Click(object sender, EventArgs e)
{
var dialog = new OpenFileDialog();
dialog.Title = "Open Image";
dialog.Filter = "bmp files (*.bmp)|*.bmp";
if (dialog.ShowDialog() == DialogResult.OK)
{
var PictureBox1 = new PictureBox();
PictureBox1.Image(dialog.FileName);
}
dialog.Dispose();
}
You have to create an instance of the Bitmap class, using the constructor overload that loads an image from a file on disk. As your code is written now, you're trying to use the PictureBox.Image property as if it were a method.
Change your code to look like this (also taking advantage of the using statement to ensure proper disposal, rather than manually calling the Dispose method):
private void button1_Click(object sender, EventArgs e)
{
// Wrap the creation of the OpenFileDialog instance in a using statement,
// rather than manually calling the Dispose method to ensure proper disposal
using (OpenFileDialog dlg = new OpenFileDialog())
{
dlg.Title = "Open Image";
dlg.Filter = "bmp files (*.bmp)|*.bmp";
if (dlg.ShowDialog() == DialogResult.OK)
{
PictureBox PictureBox1 = new PictureBox();
// Create a new Bitmap object from the picture file on disk,
// and assign that to the PictureBox.Image property
PictureBox1.Image = new Bitmap(dlg.FileName);
}
}
}
Of course, that's not going to display the image anywhere on your form because the picture box control that you've created hasn't been added to the form. You need to add the new picture box control that you've just created to the form's Controls collection using the Add method. Note the line added to the above code here:
private void button1_Click(object sender, EventArgs e)
{
using (OpenFileDialog dlg = new OpenFileDialog())
{
dlg.Title = "Open Image";
dlg.Filter = "bmp files (*.bmp)|*.bmp";
if (dlg.ShowDialog() == DialogResult.OK)
{
PictureBox PictureBox1 = new PictureBox();
PictureBox1.Image = new Bitmap(dlg.FileName);
// Add the new control to its parent's controls collection
this.Controls.Add(PictureBox1);
}
}
}
Works Fine.
Try this,
private void addImageButton_Click(object sender, EventArgs e)
{
OpenFileDialog of = new OpenFileDialog();
//For any other formats
of.Filter = "Image Files (*.bmp;*.jpg;*.jpeg,*.png)|*.BMP;*.JPG;*.JPEG;*.PNG";
if (of.ShowDialog() == DialogResult.OK)
{
pictureBox1.ImageLocation = of.FileName;
}
}
You should try to:
Create the picturebox visually in form (it's easier)
Set Dock property of picturebox to Fill (if you want image to fill form)
Set SizeMode of picturebox to StretchImage
Finally:
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Title = "Open Image";
dlg.Filter = "bmp files (*.bmp)|*.bmp";
if (dlg.ShowDialog() == DialogResult.OK)
{
PictureBox1.Image = Image.FromFile(dlg.Filename);
}
dlg.Dispose();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
if (open.ShowDialog() == DialogResult.OK)
pictureBox1.Image = Bitmap.FromFile(open.FileName);
}
You, can also try like this, PictureBox1.Image = Image.FromFile("<your ImagePath>" or <Dialog box result>);
PictureBox.Image is a property, not a method. You can set it like this:
PictureBox1.Image = System.Drawing.Image.FromFile(dlg.FileName);
You can try the following:
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog fDialog = new OpenFileDialog();
fDialog.Title = "Select file to be upload";
fDialog.Filter = "All Files|*.*";
// fDialog.Filter = "PDF Files|*.pdf";
if (fDialog.ShowDialog() == DialogResult.OK)
{
textBox1.Text = fDialog.FileName.ToString();
}
}
It's simple. Just add:
PictureBox1.BackgroundImageLayout = ImageLayout.Zoom;

Categories

Resources