I have a program that scans in document bar codes and then allows for the user to click on a link which will open up a PDF associated with that bar code. My program works fine however I am running into a bug(?) in my code where every so often instead of opening the PDF once, the system will open it multiple times (5+) and it doesn't seem to be consistent. I'm hesitant to rewrite the code completely since it is actually working, it is simply inconvenient to have to close multiple windows. The method that I believe is causing the problem is below. Any help would be greatly appreciated as I am not sure where to start.
private void dgDisplay_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
id = (int)comboBox1.SelectedValue;
string ImagePath = getImagePath(id);
string filename = "";
if (e.ColumnIndex == 1)
{
filename = dgDisplay[e.ColumnIndex, e.RowIndex].Value.ToString();
filename = #ImagePath + filename + ".tif";
if (File.Exists(filename))
{
Process.Start(filename);
}
else
{
MessageBox.Show(filename);
}
}
}
Related
I'm creating a C# Windows Form Application with a single form, which creates some files. But i want these to be temporary.
So what i intend to do is this.
All the files which are created during the program execution period will be deleted after the form closes(I tried to delete them before closing the form, but i get an error, so that's why i need to delete it after the form closes). But the problem is just cant seem to do it. I tried searching some websites but i couldn't get a solution.So here i am. If anyone knows how to execute some code after form closes ,pls share it with me
Thanks in advance.
----Edit----
Sry guys for not adding the code here.
Im a noob in application development.
Anyways,here's what i tried:
private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
{
int Length = Directory.GetFiles("C:\\Windows\\Temp\\Yamin").Length;
for( int i = 0; i < Length; i++ )
{
File.Delete("C:\\Windows\\Temp\\Yamin\\" + i + ".jpg");
}
}
Also tried this :
private void Form1_FormClosed(Object sender, FormClosedEventArgs e)
{
int Length = Directory.GetFiles("C:\\Windows\\Temp\\Yamin").Length;
for (int i = 0; i < Length; i++)
{
File.Delete("C:\\Windows\\Temp\\Yamin\\" + i + ".jpg");
}
}
I start the program for testing. Everything works fine but when i close the form i expect the functions above to be executed, but they are not being executed.
Thats my problem.
Again, thanks in advance.
Please check the documentation of the Directory.GetFiles Method (String). Perhaps that is a problem or perhaps the code you posted is inconsistent with your actual code.
I created a Windows Forms application and put two buttons on the form, a Create button and a Delete button.
The following is the code for the Create button:
string Name = string.Empty;
for (int i=0; i<3; ++i)
{
try
{
Name = Folder + "SO36922336-" + i.ToString() + ".txt";
StreamWriter sw = new StreamWriter(Name);
sw.WriteLine("File created using StreamWriter class.");
sw.Close();
sw.Dispose();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message + "\r\n" + Name);
}
}
The following is the code for the Delete button:
string[] Files = Directory.GetFiles(Folder, "SO36922336-*.txt");
foreach (string fn in Files)
{
File.Delete(fn);
}
The code works for me. So either you are doing Directory.GetFiles incorrectly or the problem is in code that you did not show or both. You don't need to do the delete outside of the form.
The easiest solution is to have the OS take care of those temporary files. To do so, call the File.Create overload1) taking a FileOptions argument, and pass DeleteOnClose. That way the file is automatically deleted by the system, once all handles to it are closed. Added bonus: If your application terminates due to a crash, the OS will still clean up the file after you.
1) If you don't know what value to pass for the bufferSize parameter, just pick the default: 4096.
I am a beginner in programming and it may seem a little funny to ask questions like this, but i have this code :
protected void OnSaveActionActivated (object sender, EventArgs e)
{
FileFilter filter = new FileFilter();
filter.Name = "Text files";
filter.AddPattern ("*.txt");
FileChooserDialog fcd = new FileChooserDialog ("... ?", this,
FileChooserAction.Save, "Cancel", ResponseType.Cancel, "OK", ResponseType.Accept);
if ((int)fcd.Run () == (int)ResponseType.Accept) {
System.IO.StreamWriter sw= new System.IO.StreamWriter(fcd.Filename);
sw.Write(textview1);
fcd.Filter = filter;
fcd.Destroy ();
} else {
fcd.Destroy ();
}
fcd.Destroy ();
Tho my Open file version works perfectly, I cant seem to make files to save properly into txt files, and i just dont understand anymore.
Sos :(
If textView1 is an actual control, then
sw.Write(textview1);
will not do what you want. Instead, try
sw.Write(textview1.Text);
which will write out the actual contents of the control, not the control itself.
Also, as #HighCore mentioned, it is much simpler to do
File.WriteAllText(file_path, textView1.Text);
To begin with, I'm relatively new to programming. I went through some introductory C# training for my new job, and it's the first language I've worked with.
I recently had a business problem that I decided to solve using C#, both to save time (I had hoped) and to learn more C# in the process. The business problem I mentioned was this: I had 600+ Word files that I needed to audit. For each document, I had to make sure that...
There was no text with strike-through anywhere in the document.
Track Changes was disabled.
There were no pending changes (as in changes that were made while
Track Changes was enabled and have yet to be accepted or
rejected).
There were no comments.
It would have been fastest to have my program iterate through all of the documents, making changes as it went along. But because of the nature of this assignment I wanted to make the changes manually, limiting the program's use to generating a list of files (out of the 600) where changes were necessary, and detailing what changes needed to be made for each of those files.
So, I have a button that calls up a FolderBrowserDialog.
private void AddFolderButtonClick(object sender, EventArgs e)
{
var folderBrowser = new FolderBrowserDialog();
if (folderBrowser.ShowDialog() != DialogResult.OK)
{
return;
}
this.progressBar1.Visible = true;
this.progressBar1.Style = ProgressBarStyle.Marquee;
this.Cursor = Cursors.WaitCursor;
var args = new List<string>(Directory.EnumerateDirectories(folderBrowser.SelectedPath));
// Get list of files in selected directory, adding to list of directories
args.AddRange(Directory.EnumerateFiles(folderBrowser.SelectedPath));
this.displayListBox.BeginUpdate();
foreach (string path in args)
{
if (File.Exists(path))
{
// This path is a file
this.ProcessFile(Path.GetFullPath(path));
}
else if (Directory.Exists(path))
{
// This path is a directory
this.ProcessDirectory((Path.GetFullPath(path)));
}
else
{
Console.WriteLine(Resources.Finder_Invalid_File_Or_Directory, path);
}
}
this.displayListBox.EndUpdate();
this.progressBar1.Visible = false;
this.progressBar1.Style = ProgressBarStyle.Continuous;
this.Cursor = Cursors.Default;
}
Together, the following two methods iterate through all subdirectories and files to create a full list of all files below the top level directory selected through the FolderBrowserDialog:
private void ProcessDirectory(string targetDirectory)
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectory);
foreach (string fileName in fileEntries)
{
this.ProcessFile(fileName);
}
// Recurse into subdirectories of this directory.
string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach (string subdirectory in subdirectoryEntries)
{
this.ProcessDirectory(subdirectory);
}
}
private void ProcessFile(string path)
{
Console.WriteLine(Resources.Finder_File_Processed, path);
string fileName = Path.GetFileName(path);
if (fileName == null || fileName.StartsWith(#"~$") || this.selectedFilesList.Contains(path))
{
return;
}
this.selectedFilesList.Add(path);
this.filePathsCountLabel.Text = (#"Count: " + this.selectedFilesList.Count);
this.displayListBox.Items.Add(path);
}
Once all this code has run, I get a full list of documents. I click a button and the program does what it's supposed to from here on out. Okay, cool. I mentioned before that half of the reason I chose to use C# to solve this was for the sake of learning. At this point I've got everything I need but what I really want to know is how can I implement threading to make the GUI responsive while the list of files is being generated? I've looked through several examples. They made sense. For some reason I just can't get my head around it for this application though. How can I make the whole process of processing subdirectories and files happen without locking up the GUI?
I believe what you need could be found here.
In short, to use a backgroundworker which does all the work on a separate thread thus prevents GUI freezes, first you instantiate BackgroundWorker and handle the DoWork event. Then you call RunWorkerAsync, optionally with an object argument.
As a skeleton code:
class myClass
{
static BackgroundWorker myBw = new BackgroundWorker();
static void Main()
{
myBw .DoWork += myBw_DoWork;
myBw .RunWorkerAsync ("an argument here");
Console.ReadLine();
}
static void myBw_DoWork (object sender, DoWorkEventArgs e)
{
// This is called on the separate thread, argument is called as e.Argument
// Perform heavy task...
}
}
You have to create a separate thread to process your work. Look at this if you are using .NET 4.0+ or this for older versions.
With Task, you can write
Task.Factory.StartNew(() => DoAction()
where DoAction is your function that starts to process data.
But do not forget to use Invoke, if you want to act with GUI from separate thread. For example, if you want to update some Label text from separate thread, you have to do this
label1.Invoke(() => label1.Text = "Some Text");
so I made a program that creates a registry key on the pc, that adds an option to push your file to your device. (The program itself pushes files to your Android sd card.)
Everything works well, or at least should, once I figure out this issue. When I right-click on an item and choose my command (which is to open up with my program) my program just opens up, but no arguments are passed.
A month ago, I designed a program that opens when the user double clicks (just double click, not right-clicking through context menu) a file, it opened the specific program, and from there I was able to grab the arguments.
Why can't I from the context menu?
Thanks, sorry for lengthy post.
And here's part of my code:
private void Form1_Load(object sender, EventArgs e)
{
string c = textBox3.Text;
string[] args = System.Environment.GetCommandLineArgs();
try
{
string location = args[1];
MessageBox.Show(location);
//For testing purposes only
Properties.Settings.Default.thinglocation = location;
Properties.Settings.Default.Save();
Process();
}
catch
{
}
Here's the registry code. BTw string c is "C:\File push.exe" the location of my program.
string MenuName = "*\\shell\\NewMenuOption";
string Command = "*\\shell\\NewMenuOption\\command";
RegistryKey regmenu = null;
RegistryKey regcmd = null;
try
{
regmenu = Registry.ClassesRoot.CreateSubKey(MenuName);
if (regmenu != null)
regmenu.SetValue("", "Push to Android");
regcmd = Registry.ClassesRoot.CreateSubKey(Command);
if (regcmd != null)
regcmd.SetValue("", c +"%1");
}
catch (Exception ex)
{
MessageBox.Show(this, ex.ToString());
}
finally
{
if (regmenu != null)
regmenu.Close();
if (regcmd != null)
regcmd.Close();
I assume that you have created a registry entry which creates the context menu item which you are using to launch your program. Likelihood is that you need to add ' %1' after the name of the exe you want to launch. In the context menu registry entries %1 represents the selected file, so adding this should launch your program and provide the name of the selected file as the single argument.
the reason why it worked before with the double click is that windows will launch the default program for the file double clicked, with the double clicked file as the argument.
Did you try looking in the sender or the EventArgs parameters? I would think their might be something in there. That's just a guess though. If its just a double click then why would there be any arguments? Maybe I am just misunderstanding that point. Anyways, maybe that helps. If not maybe you could clarify a little bit where the arguments are supposed to come from.
Erik
This is kinda strange, let me try to explain it as best as possible:
When I create a new file and Save it, it saves correctly (test.xml).
When I make changes to this file and Save it, it saves correctly (to test.xml)
When I make changes again to this file or just choose Save As, it works correctly (newtest.xml)
However, when I do a file open, make changes to a file (test.xml) and click Save it is saving to (newtest.xml).
This is in my MainForm.cs
if (this.openEditorDialog1.ShowDialog(this) == DialogResult.OK && editForm != null)
{
editForm.Close();
editForm = new EditorForm(this);
editForm.OpenFile(this.openEditorDialog1.FileName);
editForm.Closing += new CancelEventHandler(EditorForm_Closing);
editForm.MdiParent = this;
editForm.Show();
}
private void biFileSave_Click(object sender, EventArgs e)
{
if (!editForm.HasFileName)
{
if (this.saveEditorDialog1.ShowDialog(this) == DialogResult.OK)
{
this.ActiveDiagram.SaveSoap(this.saveEditorDialog1.FileName);
editForm.FileName = this.saveEditorDialog1.FileName;
}
}
else
{
this.ActiveDiagram.SaveSoap(this.saveEditorDialog1.FileName);
}
This is in my EditorForm.cs
public void OpenFile(string strFileName)
{
diagramComponent.LoadSoap(mainForm.openEditorDialog1.FileName);
this.FileName = mainForm.openEditorDialog1.FileName;
this.tabControl1.SelectedTab = DiagramTab;
}
I'm sure it has to do with the what I'm doing in the EditoForm but I can't seem to figure it out.
else
{
this.ActiveDiagram.SaveSoap(this.saveEditorDialog1.FileName);
It looks like you want:
this.ActiveDiagram.SaveSoap(editForm.FileName);
It must have to do with mainForm.openEditorDialog1.FileName. Use a FileName property of the form that does the saving. When you open the file, set the fileName to mainForm.openEditorDialog1.FileName. When you SaveAs, set the FileName property there, too. This way, whenever the current file, changes you set the FileName property appropriately. Then, when it comes time to save the file, you always have the correct filename.
In summary, only use the .FileName property of the SaveAs dialog or the FileOpen dialog right after you use them.