C# StreamWriter in separate class - c#

I have a Textbox and a button in form1, and when i write in the textbox i can save it to a file on the computer using my button. This is placed inside my button
public void button1_Click(object sender, EventArgs e)
{
string FileName = "C:\\sample\\sample.txt";
System.IO.StreamWriter WriteToFile;
WriteToFile = new System.IO.StreamWriter(FileName);
WriteToFile.Write(textBox1.Text);
WriteToFile.Close();
MessageBox.Show("Succeded, written to file");
But anyway, I want to move everything to do with streamWriter to their own class (Class1) and call it from my main form, inside the button.
If i move all the content insde the Button and move it to class1 inside a method, it claims that Textbox1 doesn't exist, obvious.
Do you have any tips or links on what i should read more about?
Best Regards
DB

You can do it in the class like this:
public class MyClass {
public static bool WriteToFile(string text){
string FileName = "C:\\sample\\sample.txt";
try {
using(System.IO.StreamWriter WriteToFile = new System.IO.StreamWriter(FileName)){
WriteToFile.Write(text);
WriteToFile.Close();
}
return true;
}
catch {
return false;
}
}
}
And in your button event:
public void button1_Click(object sender, EventArgs e){
if(MyClass.WriteToFile(textBox1.Text))
MessageBox.Show("Succeded, written to file");
else
MessageBox.Show("Failer, nothing written to file");
}

Related

File being used by another process when using File.CopyTo method

This is the code for my windows form. The goal of the form is to be able to preview a pdf on the application and then chose a folder with a drop down that you would like to copy the file to (this is what a "house" refers to in the code). This is a little project for work to make it simpler to organize files that get sent to the company. The listBox works populating with all the pdfs and the preview window works as well (this is the axAcroPDF component). But when hitting the send button to copy the file it says the file is being used by another process.
public partial class Form1 : Form { public Form1() { InitializeComponent();
}
string selectedPDF = "";
string selectedHouse = "";
DirectoryInfo currentPDF;
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "PDF Files(*.pdf) |*.pdf;";
openFileDialog1.ShowDialog();
if(openFileDialog1.FileName != null)
{
axAcroPDF1.LoadFile(openFileDialog1.FileName);
}
}
private void refreshBTN_Click(object sender, EventArgs e)
{
DirectoryInfo dinfo = new DirectoryInfo(#"C:\Users\bkamide\Desktop\ExamplePDFS");
FileInfo[] smFiles = dinfo.GetFiles("*.pdf");
foreach (FileInfo fi in smFiles)
{
pdfList.Items.Add(Path.GetFileName(fi.Name));
}
}
private void pdfList_SelectedIndexChanged(object sender, EventArgs e)
{
string firstSelectedItem = pdfList.SelectedItem.ToString();
selectedPDF = firstSelectedItem;
DirectoryInfo dinfo = new DirectoryInfo(#"C:\Users\bkamide\Desktop\ExamplePDFS\" + firstSelectedItem);
currentPDF = dinfo;
}
private void btnSend_Click(object sender, EventArgs e)
{
openFileDialog1.Reset();
axAcroPDF1.EndInit();
var sourceFile = new FileInfo(currentPDF.FullName);
var dest = Path.Combine(#"C:\Users\bkamide\Desktop\ExamplePDFS\", selectedHouse, sourceFile.FullName);
sourceFile.CopyTo(dest, true);
}
private void cbHouse_SelectedIndex(object sender, EventArgs e)
{
selectedHouse = cbHouse.SelectedIndex.ToString();
}
}
I tried in the send method to reset the openFileDialog and axAcroPDF (not sure if I did that right) to see if those were the processes that could be using the file. I also tried restarting my computer to make sure nothing in the background was using it as well. I also did try the using method but I was not quite sure how to implement it within this.

Old form still display winforms c#

I implement a form for handle excel file when click button "Start".
Event click Start button:
private void btnImport_Click(object sender, EventArgs e)
{
showFormSelectLanguage();
if (CheckSheetFile() == true) {
using (WaitingForm frm = new WaitingForm(handleExcel))
{
frm.ShowDialog(this);
}
var dialogMessage = new DialogMessage();
dialogMessage.ShowDialog(this);
} else
{
ShowDialogNotFoundSheet();
}
}
showFormSelectLanguage method display dialog for select language:
private void showFormSelectLanguage()
{
var formSelectLanguage = new FormSelectLanguage();
formSelectLanguage.ShowDialog(this);
}
ShowDialogNotFoundSheet function for check sheet excel exist:
private void ShowDialogNotFoundSheet()
{
var dialogNotFoundSheet = new DialogNotFoundSheet();
dialogNotFoundSheet.setTextContent("Not found sheet");
dialogNotFoundSheet.ShowDialog(this);
}
Event click confirm select language button at Select language form:
private void btnConfirmLanguage_Click(object sender, EventArgs e)
{
//close dialog
this.Close();
}
Event click Close button for close DialogNotFoundSheet form:
private void btnCloseDialogNotFoundSheet_Click(object sender, EventArgs e)
{
this.Close();
}
CheckSheetFile method:
private bool CheckSheetFile()
{
var isCorrectFile = false;
try
{
xlWorkBook = xlApp.Workbooks.Open(txtFilePath.Text, System.IO.FileMode.Open, System.IO.FileAccess.Read);
var xlWorkBook1 = xlWorkBook.Sheets["SheetName"];
isCorrectFile = true;
}
catch (Exception e)
{
return false;
}
return isCorrectFile;
}
Issue:
When I click Close button at DialogNotFoundSheet form. Then FormSelectLanguage from still display. It repeats. How can resolve it?
Expected 2 forms can close
Thanks!
Update:
All References btnImport_Click:
UI:
I don't exactly know what you did with btnImport_Click, but if your purpose is to disable the function of a button at a time and to enable it at another time, actually you don't have to register or unregister the click event, you can simply set button's Enabled propety.
//btnImport.Click += btnImport_Click;
btnImport.Enabled = true;
//btnImport.Click -= btnImport_Click;
btnImport.Enabled = false;
My guess of the reason of this loop is that you have called += btnImport_Click many times, but -= btnImport_Click is never (or less) run.
For instance if you do:
btnImport.Click += btnImport_Click;
btnImport.Click += btnImport_Click;
Each time btnImport is clicked, btnImport_Click will get invoked twice.

The FormClosing event seems to run after a different Form is started

I did a lot of research about this problem and tried methods but none of them worked. First I will show you what is in my application and what I want it to be with some pictures.
Picture 1
As you can see in the first picture, I open new childForms using the buttons on the main form. One of them is the form named "Price". This form saves the prices entered by the user to the json file. I do the saving process in the FormClosing event. (Yes i know but I don't want to use the "Save" button.)
Picture 2
As you can see in the second picture, the "Result" form did some mathematical operations by reading the values entered by the user in the "Price" form over json.
Now let's come to the problem, I open the "Price" form, change the values and press the result button. Results are coming, everything is great! But the results are not correct because when the "Result" Form was run it didn't wait for the current values to be saved in json. So it didn't wait for the "Price" form to close (i.e. it didn't wait for the Price.FormClosing event to complete).
To avoid this error, I open the results form after opening a different form, but this is amateurish.
I hope I was able to explain my problem clearly.
Thanks in advance for your answers and thoughts.
Code to Write Current Values to JSON File:
private void ProductPricesForm_FormClosing(object sender, FormClosingEventArgs e)
{
string jsonString = JSONOperations.getItemsAsString(products);
File.WriteAllText(JSONOperations.productsJSONPath, jsonString);
}
Code to Read JSON File:
private static void getItems()
{
using (StreamReader r = new StreamReader(JSONOperations.productsJSONPath))
{
string json = r.ReadToEnd();
products = JSONOperations.getItemsAsClass<Product>(json);
}
}
Form Opening Code:
private void buttonResult_Click(object sender, EventArgs e)
{
openChildForm(new ResultForm());
}
private void buttonProductPrices_Click(object sender, EventArgs e)
{
openChildForm(new ProductPricesForm());
}
private Form activeForm;
private void openChildForm(Form childForm)
{
if (activeForm == null)
{
startChildForm(childForm);
}
else
{
if (String.Equals(activeForm.Name, childForm.Name))
{
return;
}
else if (!String.Equals(activeForm.Name, childForm.Name))
{
activeForm.Close();
startChildForm(childForm);
}
}
}
private void startChildForm(Form childForm)
{
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
panelChildForm.Controls.Add(childForm);
panelChildForm.Tag = childForm;
childForm.BringToFront();
childForm.Show();
activeForm = childForm;
}
You can simply Hide the dialog instead of close.
First, create your childs types:
private enum FormType
{
Result = 0,
Products = 1,
//...
}
An a method to create each form:
private Form CreateChildForm(FormType formType)
{
switch (formType)
{
case FormType.Result:
return new ResultForm();
case FormType.Products:
return new ProductPricesForm();
default:
return null;
}
}
Now, in your form, add this fields:
private int _activeChildIndex = -1;
private readonly Form[] _childsForms = new Form[Enum.GetNames(typeof(FormType)).Length];
_childsForms will store each type of ChildWindow that you create. _activeChildIndex indicates the _childsForms which is active now.
private void ShowChildWindow(FormType formType)
{
var index = (int)formType;
if (this._activeChildIndex == index)
{
return;
}
if (this._activeChildIndex >= 0)
{
var activeChild = this._childsForms[this._activeChildIndex];
// TODO: Hide form
this.OnHideForm(this._activeChildIndex);
}
this._activeChildIndex = index;
if (this._childsForms[index] != null)
{
// TODO: Reset to default (or leave with last state, as you prefer)
// TODO: And show
}
else
{
// TODO: Create child form
var childForm = this.CreateChildForm(formType);
if (childForm != null)
{
this._childsForms[index] = childForm;
}
}
this.OnShowForm(this._activeChildIndex);
}
This method create a child form if not exists and show when was previously created.
In your ProductsForm, add a method to get the JSON:
public string GetProductsJson()
{
return JSONOperations.getItemsAsString(products);
}
Now, you can use OnShowForm in this way:
private void OnShowForm(int index)
{
var formType = (FormType)index;
if (formType == FormType.Result)
{
var productsForm = this._childsForms[(int)FormType.Products];
if (productsForm != null)
{
var json = productsForm.GetProductsJson();
}
}
}
When you activate your result form, search your products form. If was previously created, get the Json. You don't need save to file the json to use here. Save it if you need for other reason.
Do some changes in FormClosing:
private void ProductPricesForm_FormClosing(object sender, FormClosingEventArgs e)
{
// Do this if you need
string jsonString = GetProductsJson();
File.WriteAllText(JSONOperations.productsJSONPath, jsonString);
// TODO: You need a flag to know when are you closing the app.
// In that case, don't cancel
e.Cancel = true;
}
UPDATE
I don't like this solution but may be that you are waiting for:
First, add a method to get the Json in your Product form:
public string GetJson()
{
return JSONOperations.getItemsAsString(products);
}
And a field in your main form:
private string _productsJson;
Instead of a file, use this string. You also can save to file if you need for other purposes.
Change this other method:
private void buttonProductPrices_Click(object sender, EventArgs e)
{
var form = new ProductPricesForm();
form.FormClosing += (sender2, e2) => this.OnProductsPrices(form.GetJson());
openChildForm(form);
}
It do the same as you was doing and also get the closing event to get the Json and invoke to OnProductsPrices with that string.
private void OnProductsPrices(string json)
{
if (_productsJson != json)
{
_productsJson = json;
var form = activeForm as ResultForm;
if (form != null)
{
form.DoSomethingWithTheJson(json);
}
}
}
If the Json doesn't change, you don't need to do anything. When it's changed, you update your _productsJson and check if current form is ResultForm. In this case, you load the Json or do whatever you do with the Json in that Form.
Also, you must use _productsJson when you create the ResultForm, like know, that I suppose you get from file. In this way, you use the json always when you create ResultForm or later, when the ProductsForm is closed.
private void buttonResult_Click(object sender, EventArgs e)
{
var form = new ResultForm();
openChildForm(form);
if (!string.IsNullOrEmpty(_productsJson))
form.DoSomethingWithTheJson(_productsJson);
// Or do the same in the constructor and manage inside the form, calling to DoSomethingWithTheJson
//var form = new ResultForm(_productsJson);
}

Using Visual Studio and Windows Forms (C#) to upload and rename file to network drive

Here's some code I'm working on:
private void Form1_Load(object sender, EventArgs e)
{
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
{
OpenFileDialog openFileDialog1 = new OpenFileDialog
{
InitialDirectory = #"C:\",
Title = "Add a PDF",
CheckFileExists = true,
CheckPathExists = true,
DefaultExt = "pdf",
Filter = "pdf files (*.pdf)|*.pdf",
FilterIndex = 2,
RestoreDirectory = true,
ReadOnlyChecked = true,
ShowReadOnly = true
};
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = openFileDialog1.FileName;
string myFile = textBox1.Text;
Console.WriteLine(myFile);
}
}
}
private void button2_Click(object sender, EventArgs e)
{
System.IO.File.Move(myFile, #"C:\testing\records\file.pdf");
}
}
}
So anyway toward the bottom at button2, I'm trying to set up a few things. I want to add a button that saves the file using the System.IO line there. But when I add the button, I can't get it to work properly. The "myFile" variable doesn't seem to be declared anymore. I'm sure this is probably the messiest code anyone will paste on here today, but a lot of it was auto-genned by Visual Studio and I'm afraid to clean it up because I'm not 100% sure what some of this stuff is. I have tried cutting and pasting the button stuff up nearer to the myFile variable declaration since it's private and maybe that's why it doesn't know what it means anymore. But when I move it up there, I get a different error regarding the "private" at the beginning of the button call.
The issue here is that you're declaring your myFile variable within the scope of the if statement and so when that if statement block exits the myFile variable goes out of scope and no longer exists.
To get it to work you need to move the creation of the myFile variable to the class level.
public class Form1 : Form
{
private string myFile;
public Form1()
{
InitializeComponent();
}
// Other code snipped out
}
Now modify your button1_Click code so that instead of creating an instance of myFile:
string myFile = textBox1.Text;
You just populate the private variable you declared in the main part of the code:
myFile = textBox1.Text;
So the if statement looks like this:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = openFileDialog1.FileName;
myFile = textBox1.Text;
Console.WriteLine(myFile);
}
You need a little modification to button2_Click:
private void button2_Click(object sender, EventArgs e)
{
// Check that myFile has some text and isn't null.
if (string.IsNullOrWhitespace(myFile))
return;
// Check that the file exists before attempting to move it.
if (File.Exists(myFile))
System.IO.File.Move(myFile, #"C:\testing\records\file.pdf");
}

Refresh ComboBox directory listing in WinForm, onClick for C#

I have a set-up a Windows form that on completion creates a .txt document containing imputed data for the user on one form and then that form can then be opened into a richTextBox on another form using a ComboBox as a selection tool.
The problem I am having is that the ComboBox does not refresh the directory listings where the .txt documents are saved after a new .txt has been created and so the user has to restart the program before it shows up in the ComboBox listing, wondering how to solve this. Possibly force the ComboBox to refresh the listings onClick of a button?
Form with ComboBox selection method on:
public Default()
{
InitializeComponent();
string[] files = Directory.GetFiles(#"C:\Modules");
foreach (string file in files)
ModuleSelectorComboBox.Items.Add(Path.GetFileNameWithoutExtension(file));
}
private void moduleToolStripMenuItem_Click(object sender, EventArgs e)
{
NewModule newmodule = new NewModule();
newmodule.Show();
}
private void ModuleSelectorComboBox_SelectedValueChanged(object sender, EventArgs e)
{
richTextBox1.Clear(); //Clears previous Modules Text
string fileName = (string)ModuleSelectorComboBox.SelectedItem;
string filePath = Path.Combine(#"C:\Modules\", fileName + ".txt");
if (File.Exists(filePath))
richTextBox1.AppendText(File.ReadAllText(filePath));
else
MessageBox.Show("There's been a problem. Please restart the program. \nError 1", "Error 1", //error 1 is file deleted while the program is running
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation,
MessageBoxDefaultButton.Button1);
}
To add I want to avoid the using of the Dialog save/open file method and is why I am using the ComboBox to do this.
Thanks in advance.
The form to create new .txt document (I don't see this as essentially needed I have just added it for reference):
private void button5_Click(object sender, EventArgs e)
{
RichTextBox newbox = new RichTextBox();
{
String Saved_Module = Path.Combine("C:\\Modules", txtModuleName.Text + ".txt");
newbox.AppendText(txtModuleName.Text + "\n" + ModuleDueDate.Text + "\n" + txtModuleInfo.Text + "\n" + txtModuleLO.Text);
newbox.SaveFile(Saved_Module, RichTextBoxStreamType.PlainText);
Directory.CreateDirectory(Path.Combine(#"C:\Modules", txtModuleName.Text));
this.Close();
}
}
First of all, encapsulate the logic of the combobox population in a method.
public Default()
{
InitializeComponent();
LoadComboBox();
}
void LoadComboBox()
{
ModuleSelectorComboBox.Items.Clear();
string[] files = Directory.GetFiles(#"C:\Modules");
foreach (string file in files)
ModuleSelectorComboBox.Items.Add(Path.GetFileNameWithoutExtension(file));
}
I suggest to open the form as a dialog form using ShowDialog method
and set the DialogResult to DialogResult.OK in the button5_Click method.
private void button5_Click(object sender, EventArgs e)
{
RichTextBox newbox = new RichTextBox();
String Saved_Module = Path.Combine("C:\\Modules", txtModuleName.Text + ".txt");
newbox.AppendText(txtModuleName.Text + "\n" + ModuleDueDate.Text + "\n" + txtModuleInfo.Text + "\n" + txtModuleLO.Text);
newbox.SaveFile(Saved_Module, RichTextBoxStreamType.PlainText);
Directory.CreateDirectory(Path.Combine(#"C:\Modules", txtModuleName.Text));
this.DialogResult = DialogResult.OK;
this.Close();
}
And then, based on the DialogResult load or do not load the combobox's items in the moduleToolStripMenuItem_Click method.
private void moduleToolStripMenuItem_Click(object sender, EventArgs e)
{
NewModule newmodule = new NewModule();
newmodule.ShowDialog();
if (result == DialogResult.OK)
{
LoadComboBox();
}
}
Update:
If you don't want to use a Dialog, you can subscribe to an FormClosing event and update the combobox in a handler to the event.
private void moduleToolStripMenuItem_Click(object sender, EventArgs e)
{
NewModule newmodule = new NewModule();
newmodule.FormClosing += F_FormClosing
newmodule.Show();
}
private void F_FormClosing(object sender, FormClosingEventArgs e)
{
LoadComboBox();
}
I suggest breaking out LoadComboBox as Valentin suggests, but using a FileSystemWatcher instantiated and disposed with the form to monitor the Modules directory and call LoadComboBox on any create/delete.

Categories

Resources