I have a print form which does the printing jobs.
When I close the print form without printing I click Close button
Close button has
private void Close_Click(object sender, EventArgs e)
{
PublicVariables.PrintData = -1;
PublicVariables.PrintStat = false;
ppc.Document = null;
ppc.Dispose();
streamToRead.Close();
this.Hide();
}
But each time I create a text file to print I delete the old.
Delete method :
public static bool DeleteData()
{
bool result=true;
string pattern = "data??.txt";
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
var matches = Directory.GetFiles(appPath, pattern);
foreach (string file in Directory.GetFiles(appPath).Intersect(matches))
{
try
{
File.Delete(file);
result =true;
}
catch (IOException e1)
{
MessageBox.Show(e1.ToString());
return false;
}
}
return result;
}
But if an IOException occurs can't delete any file.
However form load of all threads I have DeleteData() and this deletes without problem the text data.
Is there a way to delete this text file within in the thread where it's created ?
For those who will advise me to make an hidden form which will delete data. I did it I got always an IOexception error. After few IOexception errors all data??.txt files are erased but it happens randomly.
Here below two procedures which create data??.txt
http://www.turcguide.com/stack/procedures.txt
Here is the CreateDataFile(string fName) and GetNewfName(string oldName) procedures link:
http://turcguide.com/stack/createdatafile.txt
The printpreviewcontroler should block this file as when we cancel a printing document on printer it needs time.
After closing and disposing the printpreviewcontroller form, when I try to delete 4-5 attempts later the file is deleted.
My point of view it comes from printpreviewcontroller.
Related
I created simple program for save/open practice. Made a setup and associated my program with my own datatype, called it .xxx (for practice).
I managed to Save and Open code and data from textbox but only from my program. Double click (or enter from windows-desktop) open up my WindowsForm as it is but there is an empty textbox. I want my saved file to be opened on double click in the same condition as when I open it from my program. How to set that up??
Here is the code of simple app (cant post images but it simple - got 1 label and 1 textbox with open and save buttons):
private void ButOpen_Click(object sender, EventArgs e)
{
textBox1.Text = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string data = Read(openFileDialog1.FileName);
textBox1.Text = data;
}
else
{//do nothing }
}
private string Read(string file)
{
StreamReader reader = new StreamReader(file);
string data = reader.ReadToEnd();
reader.Close();
return data;
}
private void ButSave_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Something|*.xxx";
DialogResult result = saveFileDialog1.ShowDialog();
string file = saveFileDialog1.FileName.ToString();
string data = textBox1.Text;
Save(file, data);
}
private void Save(string file, string data)
{
StreamWriter writer = new StreamWriter(file);
writer.Write(data);
writer.Close();
}
NOTE:
My similar question was marked as duplicate but it is not, and this question which was referenced as duplicate Opening a text file is passed as a command line parameter does not help me.It's not the same thing...
Just wanted to find out how to configure registry so windows understand and load data inside the file, or to file save data somehow so i can open it with double click.
So someone please help. If something is not clear I will give detailed information just ask on what point.
Thanks
MSDN has some information about this:
https://msdn.microsoft.com/en-us/library/bb166549.aspx
Basically you need to create an entry in the registry so that explorer.exe knows to launch your program when that file is activated (e.g. double-clicked).
Explorer will then pass the path to the file as an argument to your program.
I have a simple textbox in my program.
Other features : another input from the user textbox1, and a button.
Once the user enters a value in textbox1, and presses the button, I start to check and print messages to the user. My problem is that I don't see those messages on real time, one at a time. The messages appear at once, in the end.
I didn't define data binding, because I thought that since it's a simple thing, I wouldn't need it, or am i wrong ?
This is a very small portion of my program, it's in the button click event handler.
MainText.AppendText("Starting Refiling...\u2028");
foreach (DocumentData doc in Docs)
{
try
{
wsProxy.RefileDocument(doc);
MainText.AppendText(String.Format("Refilling doc # {0}.{1}\u2028", doc.DocNum, doc.DocVer));
}
catch (Exception exc)
{
if (exc.Message.Contains("Document is in use") == true)
MainText.AppendText(String.Format("There was a problem refilling doc # {0}, it is in use.\u2028",doc.DocNum));
else
MainText.AppendText(String.Format("There was a problem refilling doc # {0} : {1}.\u2028", doc.DocNum, exc.Message));
}
}
You're doing all your looping/printing in the GUI thread. Basically you're giving it new items to show and not giving it time to show them. Create a background worker and let him do the work in the foreach loop that you posted. This should allow the UI thread to update the view as the text changes, instead of getting the one update at the end with all your changes. The link I posted includes examples on how to use the backgroundworker class, but here's what I'd do.
Create a background worker:
private readonly BackgroundWorker worker = new BackgroundWorker();
Initialize him:
public MainWindow()
{
InitializeComponent();
worker.DoWork += worker_DoWork;
}
Create a task for him:
void worker_DoWork( object sender, DoWorkEventArgs e)
{
// Set up a string to hold our data so we only need to use the dispatcher in one place
string toAppend = "";
foreach (DocumentData doc in Docs)
{
toAppend = "";
try
{
wsProxy.RefileDocument(doc);
toAppend = String.Format("Refilling doc # {0}.{1}\u2028", doc.DocNum, doc.DocVer);
}
catch (Exception exc)
{
if (exc.Message.Contains("Document is in use"))
toAppend = String.Format("There was a problem refilling doc # {0}, it is in use.\u2028",doc.DocNum);
else
toAppend = String.Format("There was a problem refilling doc # {0} : {1}.\u2028", doc.DocNum, exc.Message);
}
// Update the text from the main thread to avoid exceptions
Dispatcher.Invoke((Action)delegate
{
MainText.AppendText(toAppend);
});
}
}
Start him when you get the button press event:
private void Button_Click(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync();
}
I have a program that stores word documents in a database, and they are repeatedly opened, closed by the user and then saved back to the database.
when opening I place them on a temp folder.
but when closed, I want to save is back to the database and then delete it directly.
I tried this:
...
((DocumentEvents_Event)document).Close += DocumentClose;
...
delegate void MethodDelegate();
private void DocumentClose()
{
new MethodDelegate(deleteLater)();
}
void deleteLater()
{
//document.Close();
Thread.Sleep(1000);
File.Delete(this.tempDocFilePath);
}
but this don't work, and I get an error message telling me the file is already opened.
and when I uncomment "document.Close();" the next two lines are not excuted
any Ideas ?
This code is possibly subject to a race condition. NEVER trust a Sleep-solution. Wait for a specific event or poll and then take action.
Okay I solved it !
here's my code snippent:
private static Thread oThread = new Thread(new ParameterizedThreadStart(delete));
...
((DocumentEvents_Event)document).Close += DocumentClose;
...
private static void DocumentClose()
{
oThread.Start(path);
}
static void delete(object path)
{
try
{
File.Delete((string)path);
}
catch (Exception)
{
Thread.Sleep(500);
delete(path);
}
}
I can't find a solution for this problem:
I write a program, which reads all file in a directory and puts them in a listbox.
When a user select a file from a listbox, the program reads the selected file and prints out some info...
The problem is that after the firs selection my program "stop working". He don't crash, but when I try to select another file he do nothing.
I figured out, that the problem is in:
private String porocilo(String s)
{
file = "/path to file/";
TextReader tr = new StreamReader(file); //<- problem here
//...
tr.close();
return someinfo;
}
//..
//Call function:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = porocilo(listBox1.SelectedItems[0].ToString());
}
After removing that (problem) line the program normally select files, but without this I can't read files and my program don't do anything.
Can someone tell me where I'm wrong?
Br, Wolfy
If the code you posted is really the code you are using (plus the missing semicolon), then the reason you are not seeing anything happening is because your code keeps opening and reading the same file, not the file the user selected. You are setting file to a constant path/filename and read from that, and you are not making use of the s parameter.
It looks like you have a hard-coded path in your porocilo method. That is, new StreamReader is taking as it's argument, file, not s.
So it will only ever open, one file, not the file you selected.
private String porocilo(String s)
{
//file = "/path to/file" // not sure what this is...???
TextReader tr = new StreamReader(s); //<- fix here
//...
tr.close();
return someinfo;
}
In your List box Selected index change method you need to assign the selected value as shown below
//Call function:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = porocilo(listBox1.SelectedItem.Text);
}
Also check your "porocilo" function it uses the parameter corectly
i want to use a background thread for the process of loading the XML data, possibly with a progress bar to let the user know that the application is actively doing something.
i have written this code through searching the net.
i want to load a XML tree in treeview on winform when a user cliks a Browse button.
In case of a large XML file the winform freezes.So to let the user know that in background the work is going on i want to add a progress bar.i have used a background worker here.
But it is raising an exception of System.ArgumentException showing this message "The URL cannot be empty.\r\nParameter name: url" on xmlDocument.Load(txtFileName.Text); this line.
My xml file is in correct format and is at the proper location where i selected.
But i am unable to find the cause of this exception.
Can you please help out or tell me the correction in my code?
Thanks....
private void btnBrowse_Click(object sender,EventArgs e)
{
bgWorker1.RunWorkerAsync();
StripProgressBar.Value = 0;
toolStripStatusLabel1.Text = "Browsing for a Xml file";
if (open.ShowDialog(this) == DialogResult.OK)
{
txtFileName.Text = open.FileName;
initiatingTree(open.FileName); //this variable gives the name of selected file
}
while (this.bgWorker1.IsBusy)
{
StripProgressBar.Increment(1);
// Keep UI messages moving, so the form remains
// responsive during the asynchronous operation.
Application.DoEvents();
}
}//Browse button
private void bgWorker1_DoWork(object sender, DoWorkEventArgs e)
{
xmlDocument = new XmlDocument();
Thread.Sleep(5000);
xmlDocument.Load(txtFileName.Text);
btnBrowse.Enabled = false;
}
private void bgworker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Set progress bar to 100% in case it's not already there.
StripProgressBar.Value = 100;
if (e.Error == null)
{
MessageBox.Show(xmlDocument.InnerXml, "Download Complete");
}
else
{
MessageBox.Show("Failed to download file");
}
// Enable the Browse button and reset the progress bar.
this.btnBrowse.Enabled = true;
StripProgressBar.Value = 0;
toolStripStatusLabel1.Text = "work finished processing request.";
}//workerCompleted
You're starting the asynchronous process immediately when the user clicks "Browse", by calling
bgWorker1.RunWorkerAsync();
This calls the DoWork method of your background worker, which sleeps for 5 seconds, and pulls the value from txtFileName.Text whether or not the user has completed their entry in the FileOpenDialog.
You'd be better off moving the byWorker1.RunWorkerAsync() (and the busy waiting) into the if (open.ShowDialog(this) == DialogResult.OK) block.
private void btnBrowse_Click(object sender,EventArgs e)
{
StripProgressBar.Value = 0;
toolStripStatusLabel1.Text = "Browsing for a Xml file";
if (open.ShowDialog(this) == DialogResult.OK)
{
txtFileName.Text = open.FileName;
initiatingTree(open.FileName);
bgWorker1.RunWorkerAsync();
while (this.bgWorker1.IsBusy)
{
StripProgressBar.Increment(1);
// Keep UI messages moving, so the form remains
// responsive during the asynchronous operation.
Application.DoEvents();
}
}
}
For these kinds of problems, it can be helpful to put a breakpoint right where the file is going to get loaded, and see what the value is when that happens... you might notice that it's getting called with an empty string.
You might also consider the version of RunWorkerAsync that takes a parameter; you could pass the file in that way, instead of trying to read it asynchronously from the textbox.
And personally, I wouldn't use a loop that calls Application.DoEvents(); instead I'd return control back to the UI thread and then Invoke() onto it from the asynchronous thread to effect the progressbar updates.
When the method bgWorker1.RunWorkerAsync(); is called the event DoWork is fired.
Because the method is called in the beginning of the application, the file name text box is empty.
I hope you've understood.