Utillize string filename from form1 to form 2 - c#

In form 1 I have open an xml file. Now I want to able to use the string filename in Form2 so I am able to do extra feature and/or use what inside the file.
Form1
DialogResult result;
string filename;
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog fileChooser = new OpenFileDialog())
{
fileChooser.Filter = "Xml Files (*.xml)|*.xml";
fileChooser.CheckFileExists = false;
result = fileChooser.ShowDialog();
filename = fileChooser.FileName;
}
}
Form2
namespace PreviewForm
{
public partial class Preview : Form
{
int ind1 = 1;
public Preview()
{
InitializeComponent();
}
private void Preview_Load(object sender, EventArgs e)
{
//I want to able to do something like this
//XmlDocument xDoc = new XmlDocument();
//xDoc.Load(filename);
//foreach(XmlNode xNode in xdoc.SelectNode(People/People))
//{
// Label lable1 = new Label();
// label1.Text = xNode.SelectingSingleNode("Name").InnerText;
// label1.Name = "label_" + ind1;
// label1.Location = new Point(code);
// ind1++;
// this.Controls.Add(label1);
}
}
}
So I want to able to use the string filename in form1 to form2.

Just use a private field instance and add it to the constructor
namespace PreviewForm
{
private string _filename = string.Empty;
public partial class Preview : Form
{
int ind1 = 1;
public Preview(string filename)
{
InitializeComponent();
_filename = filename;
}
to use the string filename in Form2
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog fileChooser = new OpenFileDialog())
{
fileChooser.Filter = "Xml Files (*.xml)|*.xml";
fileChooser.CheckFileExists = false;
result = fileChooser.ShowDialog();
filename = fileChooser.FileName;
//for example here
PreviewForm form2=new PreviewForm(filepath);
form2.ShowDialog(this);
}
}

Solution 1 : You can send the FilePath from Form1 to the Form2 using constructor as below:
Form2 form2=new Fomr2(filepath);
form2.ShowDialog();
and create a string parameter constructor in Form2 as below:
string filepath;
public Preview(string filepath)
{
InitializeComponent();
this.filepath=filepath;
}
Solution 2: Make the filepath variable as public static in Form1 so that it can be accessible using its classname.
Try This:
public static string filepath;
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog fileChooser = new OpenFileDialog())
{
fileChooser.Filter = "Xml Files (*.xml)|*.xml";
fileChooser.CheckFileExists = false;
result = fileChooser.ShowDialog();
filename = fileChooser.FileName;
Form2 form2=new Fomr2(filepath);
form2.ShowDialog();
}
}
From Form2 :
You can access from as below:
String filepath = Form1.filepath;

Some have already posted working examples, but I'd like to give you a general overview of what can be done when you need to pass data from a class to another one.
I'm presenting you with 3 basic ways to pass your data from the first class (the sender class) to the second (the receiver class):
Constructor Injection. This is what most people have described here, and it basically mean to have a "special" constructor on your receiver class that will be called from the sender class to pass the necessary data as a parameter when the receiver class object is instantiated. The data can then be saved to a local member on the receiver class.
Setter Injection. In this case, you define a public property on the receiver class that you call from the sender class, but after the receiver has been instantiated. As with the constructor injection, you can save the data to a local member on the receiver.
Method Injection. In this case, you define a method on the receiver class that will have a parameter defined to receive the data. here you can either decide to store the data to a member of the receiver, but you could also decide to use the data directly in the method body and discard it when done.
This is by no mean an exhaustive list of how you can pass data between classes, but it will give you a good starting point.
Cheers

Related

Access RichTextBox from another class

I am new and trying to do something in c# but I dont know how to solve this prbolem.
My MainWindow.xaml.cs I have a RichTextBox with name RTB that I wanna save into text file.
I created new file Saving.cs where I would write every thing that I need for saving.
This is my code.
Saving.cs
public string VarName = "";
public void Save()
{
MainWindow main = new MainWindow();
TextRange range = new TextRange(main.RTB.Document.ContentStart, main.RTB.Document.ContentEnd);
FileStream stream = new FileStream(VarName, FileMode.Create);
range.Save(stream, DataFormats.Text);
stream.Close();
}
MainWindow.xaml.cs
private void Button_Save(object sender, RoutedEventArgs e)
{
saveDoc.VarName = SaveName.Text + ".txt";
saveDoc.Save();
}
Everything works fine except that there is nothing in saved document.
My problem is that I really dont know how to acces RTB from different file. It works when I put this code into MainWindow.xaml.cs but not when its in different file like Saving.cs.
I also dont know if its ok to have this in my Saving.cs "MainWindow main = new MainWindow();" or how to aproach this problem.
Thanks for your help kind stranger.
I hope these code snippets can help to solve your problem
MainWindow.xaml.cs :
private void Button_Click(object sender, RoutedEventArgs e)
{
// Note: Please dont forget about OOP,
// dont use 'public' mode on class fields (VarName)
SaveDoc.MyProperty = SaveName.Text + ".txt";
TextRange range = new TextRange(RTB.Document.ContentStart,RTB.Document.ContentEnd);
//You can pass this 'range' field as a parameter to Class 'SaveDoc'
SaveDoc.Save(range);
}
Saving.cs :
class SaveDoc
{
private static string VarName;
//Use Properties to access fields from another classes
public static string MyProperty
{
get { return VarName; }
set { VarName = value; }
}
// Here you can pass the 'range' field from MainWindow as a parameter
public static void Save(TextRange range)
{
FileStream stream = new FileStream(VarName, FileMode.Create);
range.Save(stream, DataFormats.Text);
stream.Close();
}
}
Also you can do like this:
MainWindow.xaml.cs :
private void Button_Click(object sender, RoutedEventArgs e)
{
// Note: Please dont forget about OOP,
// dont use 'public' mode on class fields (VarName)
SaveDoc.MyProperty = SaveName.Text + ".txt";
string range = new TextRange(RTB.Document.ContentStart,RTB.Document.ContentEnd).Text;
//You can pass this 'range' field as parameter to Class 'SaveDoc'
SaveDoc.Save(range);
}
Saving.cs :
class SaveDoc
{
private static string VarName;
//Use Properties to access fields from another classes
public static string MyProperty
{
get { return VarName; }
set { VarName = value; }
}
// Here you can pass the 'range' field from MainWindow as a parameter
public static void Save(string range)
{
// Standart algorithm to write something in file:
FileStream stream = new FileStream(VarName, FileMode.Create);
//convert string to bytes
byte[] buf = Encoding.Default.GetBytes(range);
// writing an array of bytes to a file
stream.Write(buf, 0, buf.Length);
stream.Close();
}
}

Pass along global variable to class

I am trying to pass a string to a public class (customPanel).
But the "teststring" is never passed on and written to the testfile.txt?
The testfile.txt writes an empty string.
private void button1_Click(object sender, EventArgs e)
{
customPanel cp = new customPanel();
cp.getinfo = "teststring";
}
public class customPanel : System.Windows.Forms.Panel
{
public String getinfo { get; set; }
public customPanel() { InitializeComponent(); }
private void InitializeComponent()
{
String gi = getinfo;
System.IO.FileStream fs = new System.IO.FileStream("C:/folder1/testfile.txt", System.IO.FileMode.Append, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
System.IO.StreamWriter writer = new System.IO.StreamWriter(fs);
writer.WriteLine(gi); writer.Close(); fs.Close();
}
}
The problem you’re having is happening because of the order of execution of your code.
Basically when you call new customPanel(), that’s when the constructor method controlPanel() is going to be called. So when you set the getInfo value, your InitializeComponent() method was already called.
Without knowing better about your context, the easy solution would be to pass the string as a parameter to your constructor. Basically switch controlPanel() to receive a string variableName as a parameter, like this controlPanel(string variableName)and then before calling InitializeComponent(); set the value of the property with a this.getInfo = variableName;.
Let me know if this helped!
Take care.

How can the scope be changed in a WinForms app to carry variables from a method to an object sender?

I am trying to carry the variables from the array over to the button click action. I can't find the way to set the scope to allow for this to work.
I have tried changing the modifiers to public, private, static, void, string, string[] etc.
I have also made all of the objects in the WinForms app set to Public
public partial class AutoPay : Form
{
public AutoPay()
{
InitializeComponent();
}
public void HeaderInformation(string dateAndTime, string fileNumber)
{
dateAndTime = DateTime.Now.ToString();
fileNumber = txtFileNumber.Text;
string[] headerArray = new string[2];
headerArray[0] = dateAndTime;
headerArray[1] = fileNumber;
}
public void BtnSave_Click(object sender, EventArgs e)
{
HeaderInformation(headerArray[0], headerArray[1]);
}
}
the headerArray[0] under the BtnSave_Click action has the red line under it showing that it is outside of the scope.
Try declaring the headerArray as a Property of the class
As was mentioned... you need to declare the headerArray outside the method... Also... it looks like you are trying to add information to the array before the array has information... try it this way(there are many other ways to do this too ;) ):
public partial class AutoPay : Form
{
private string[] headerArray; // <-- declare it here...
public AutoPay()
{
InitializeComponent();
headerArray = new string[2]; // <-- sometimes the normal way to initialize...
}
public void HeaderInformation(string dateAndTime, string fileNumber)
{
// reinitialize headerArray for safety....
headerArray = new string[2];
headerArray[0] = dateAndTime;
headerArray[1] = fileNumber;
}
public void BtnSave_Click(object sender, EventArgs e)
{
HeaderInformation(DateTime.Now.ToString(), txtFileNumber.Text);
}
}
or
public void HeaderInformation()
{
// reinitialize headerArray for safety....
headerArray = new string[2];
headerArray[0] = DateTime.Now.ToString();
headerArray[1] = txtFileNumber.Text;
}
public void BtnSave_Click(object sender, EventArgs e)
{
HeaderInformation();
}

Using OpenFileDialog and StreamReader

There are two classes, one to cover the form (class 1) and the other to cover what gets displayed on the form (class 2). I'm trying to call a method in class 1 from class 2 to display certain information in a text box. I keep getting the error:
An object reference is required for the non-static field, method, or property
I've encountered this error before and been able to make it through, but nothing I've attempted so far has helped in this instance. I'm posting code for both the classes.
Class 1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
namespace Project6
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Stream myStream = null;
//Create an instance of the open file dialog box
OpenFileDialog ofd = new OpenFileDialog();
//Set parameters, filter options, and filter index
ofd.InitialDirectory = "c:\\";
ofd.Filter = "Text Files (.txt)|*.txt";
ofd.FilterIndex = 2;
ofd.Multiselect = false;
if (ofd.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = ofd.OpenFile()) != null)
{
using (myStream = ofd.OpenFile())
{
StreamReader reader = new StreamReader(myStream);
string studentInformation = "";
string[] studentInformationArray = new string[11];
studentInformation = reader.ReadLine();
while ((studentInformation = reader.ReadLine()) != null)
{
studentInformationArray = studentInformation.Split(',');
Student newStudent = new Student(studentInformationArray);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.Text = Student.GetName(); //This generates the compiler error
textBox1.Select(6, 5);
MessageBox.Show(textBox1.SelectedText);
}
}
}
Class 2:
using System;
using System.Windows.Forms;
namespace Project6
{
class Student
{
//Initialize variables
private string[] studentInformationArray;
//Constructor that accepts the studentInformationArray as an argument
public Student(string[] studentInformationArray)
{
this.studentInformationArray = studentInformationArray;
}
public Student()
{
string className = studentInformationArray[1];
string semester = studentInformationArray[2];
string picture = studentInformationArray[3];
int project1 = Convert.ToInt32(studentInformationArray[4]);
int project2 = Convert.ToInt32(studentInformationArray[5]);
int project3 = Convert.ToInt32(studentInformationArray[6]);
int project4 = Convert.ToInt32(studentInformationArray[7]);
int project5 = Convert.ToInt32(studentInformationArray[8]);
int project6 = Convert.ToInt32(studentInformationArray[9]);
int midtermExam = Convert.ToInt32(studentInformationArray[10]);
int finalExam = Convert.ToInt32(studentInformationArray[11]);
}
public string GetName()
{
string studentName;
studentName = studentInformationArray[0];
return studentName;
}
}
}
That's because that's not how you use the OpenFileDialog. Take a look at this example hosted by the MSDN here:
Edit: answering to your edited question. You will always get a NullReferenceException in the Student() constructor because you are never assigning something to your studentInformationArray. So you can fix it like this:
public Student()
{
studentInformationArray = new studentInformationArray[12];
string className = studentInformationArray[1];
// rest of your code...
}
However, you should take into account that studentInformationArray will be an empty array unless you assign something to it. Since you have a Student() overload that takes a string[], I'd suggest you that you either remove the default constructor or make it call the overloaded with default information, like this:
public Student(string[] studentInformationArray)
{
string className = studentInformationArray[1];
// rest of your code...
int project1 = int.Parse(studentInformationArray[4]); // always prefer int.Parse() instead of Convert.ToInt32()
// rest of your code...
this.studentInformationArray = studentInformationArray;
}
public Student()
{
string[] defaultInformation = new string[12];
// add information
defaultInformation[0] = "some information";
// ...
new Student(defaultInformation);
}
Some more points to take into account:
Class-level fields/properties should be spelled in Pascal Case (first letter of each word in uppercase, rest in lowercase)
Try to never use this.variableName = variableName.
Variables names should never include the type of the variable, that's redundant.
So, for example, change this:
private string[] studentInformationArray;
for this:
private string[] StudentInformation;
Answering your last question, regarding the compiler error, you need a reference to the Student read in order to get its name. You could do something like this:
public partial class Form1 : Form
{
private Student StudentRead;
// rest of your code...
// from your read method:
StudentRead = new Student(studentInformationArray);
// and finally:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.Text = StudentRead.GetName();

c# Passing parameters on event from another class to main class

I have a main (Form1) Class, and a second class which handles all the Serial Communication (ComPort)
When a new data is received through the Serial port (Event), I'd like to pass it to the Form1 and do some manipulation on this data.
Little Example: Creating long string from received data
Form1.cs
public partial class Form1 : Form
{
//Creating instance of SerialCommunication.
....
....
string receivedString = ""; //Here I will store all data
public void addNewDataMethod(string newDataFromSerial)
{
receivedString = receivedString + newDataFromSerial;
MessageBox.Show(receivedString);
}
}
SerialCommunication.cs
public partial class SerialCommunicationPort
{
constructor()
{
.... //open serial port with the relevant parameters
ComPort.DataReceived += new SerialDataReceivedEventHandler(ComPortBufferRead);//Create Handler
}
public void ComPortBufferRead(object sender, SerialDataReceivedEventArgs e)
{
//create array to store buffer data
byte[] inputData = new byte[ComPort.BytesToRead];
//read the data from buffer
ComPort.Read(inputData, 0, ComPort.BytesToRead);
//***** What should I write here in order to pass "inputData" to Form1.addNewDataMethod ?
}
}
I Tried the following:
Form1 Form;
Form1.addNewDataMethod(inputData.ToString());
The above code will generate an error: use of unassigned local variable "Form"
Form1 Form1 = new Form1();
Form1.addNewDataMethod(inputData.ToString());
the above will create a new instance of Form1, and will not contain the previous received data.
Any Suggestions ?
Create an event in SerialCommunication class which will be raised when data is arrived:
public partial class SerialCommunicationPort
{
public event Action<byte[]> DataReceived;
public void ComPortBufferRead(object sender, SerialDataReceivedEventArgs e)
{
byte[] inputData = new byte[ComPort.BytesToRead];
ComPort.Read(inputData, 0, ComPort.BytesToRead);
if (DataReceived != null)
DataReceived(inputData);
}
}
Then subscribe to this event in your form.
public partial class Form1 : Form
{
SerialCommunication serialCommunication;
public Form1()
{
InitializeComponent();
serialCommunication = new SerialCommunication();
serialCommunication.DataReceived += SerialCommunication_DataReceived;
}
private void SerialCommunication_DataReceived(byte[] data)
{
// get string from byte array
// and call addNewDataMethod
}
}
If you want to follow Microsoft coding guidelines for WinForms, then instead of Action<byte[]> delegate you should use EventHandler<DataReceivedEventArgs> delegate, where DataReceivedEventArgs is class inherited from EventArgs.
probably the best way would be to use events. Define an event which would an EventArgs parameter that would take a string. In Form1 subscribe to the event and in your serial communication class just trigger the event passing the string you want to the eventargs.
The way you wanted should work as well, but something like this:
Form1 Form = new Form1();
Form.Show(); // to display it...
/// to other stuff...
Form.addNewDataMethod(inputData); // call the method on the INSTANCE which you opened!
similar to usage of methods, you could define a property in Form1 :
private string _myString = "";
public string MyString {
private get {
}
set {
string _myString= value;
// to with the string what you want
}
}
and then similar to the method call use
Form.MyString = "abc";
Hope this help!

Categories