I have two forms (in the same namespace), Form1 which acquires data from images, and GraphForm, which sould plot the data as a surface graph, using the ILNumerics framework.
I had never done such a construction with two forms (fairly new to C#, and coding as a whole for that matters), and I can't figure out why my code doesn't work, as it's almost copy/pasted from a previous question asked here (Sujith H S answer). I tried other constructions described in various similar questions as well, with the same result : the second form and the ILNumerics plotting interface appear, but are empty.
Here is my version of the answer I linked :
IN FORM1 :
// Form creation
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static ILInArray<double> CrossCorrExpMatrixReShiftedILN;
//Here is my whole data acquisition code, about 800 lines long
ILInArray<double> CrossCorrExpMatrixReShiftedILN = CrossCorrExpMatrixReShifted;
GraphForm Form2 = new GraphForm();
Form2.Show();
IN GRAPHFORM :
public partial class GraphForm : Form
{
public GraphForm()
{
InitializeComponent();
}
private void GraphForm_Load(object sender, EventArgs e)
{
ILInArray<double> GraphData = Form1.CrossCorrExpMatrixReShiftedILN;
//Here I use GraphData to plot the surface
}
Does anyone have an idea why it doesn't work ?
Have you tried passing the ILInArray<double> object into GraphForm's constructor and setting it to a local variable? So something like the below?
IN FORM1 :
GraphForm Form2 = new GraphForm(CrossCorrExpMatrixReShiftedILN);
Form2.Show();
IN GRAPHFORM :
public partial class GraphForm : Form
{
private ILInArray<double> CrossCorrExpMatrixReShiftedILN;
public GraphForm(ILInArray<double> pCrossCorrExpMatrixReShiftedILN)
{
InitializeComponent();
CrossCorrExpMatrixReShiftedILN = pCrossCorrExpMatrixReShiftedILN;
}
private void GraphForm_Load(object sender, EventArgs e)
{
ILInArray<double> GraphData = CrossCorrExpMatrixReShiftedILN;
//Here I use GraphData to plot the surface
}
I found the solution.
In the design tab for the GraphForm form, the Load event was NOT associated with the GraphForm_Load code bit. I don't know why it didn't associate automatically.
I found this by placing breakdown points along the GraphForm code, and noticing that the GraphForm_Load code didn't run at all.
Related
I have 2 forms, let's call them form1 and form2. Inside form1 i have created a method that connects to an access database, and also inserts the values from the database into a combobox. My question is : how do i call my method which is inside my form1, for a combobox inside form2? The error that i get says The name "MyComboBoxName" does not exist in the current context.
I have tried to use inheritence between my 2 classes, but then i get 2 of the same comboboxes.
The easiest solution is to define your method statically in the first form:
public partial class Form1 : Form
{
public static void CustomMethod()
{
//Your codes
}
public Form1()
{
InitializeComponent();
}
}
Then call it from the second form:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Form1.CustomMethod();
}
}
My problem is, I can't invoke a message into the TextBox and I can't understand why.
There is a main class and a second class, both with call to the other one.
Where is my error?
using System;
using System.Windows.Forms;
namespace Class_Test___Invoke
{
public partial class MAINFORM : Form
{
public MAINFORM()
{
InitializeComponent();
_INVOKER = this;
}
private MAINFORM _INVOKER;
private static CLASS _CLASS = new CLASS();
private void button1_Click(object sender, EventArgs e)
{
_CLASS._MESSENGER();
}
public void _LOGGING(string _MESSAGE)
{
if (InvokeRequired)
{
_INVOKER.Invoke(new Action<string>(_LOGGING), new object[] { _MESSAGE });
textBox_ausgabe.AppendText(_MESSAGE);
return;
}
else textBox_ausgabe.AppendText(_MESSAGE);
}
}
}
namespace Class_Test___Invoke
{
class CLASS
{
private MAINFORM _MAINFORM = new MAINFORM();
public void _MESSENGER()
{
_MAINFORM._LOGGING("Test");
}
}
}
You are assuming that the _MAINFORM you create in the CLASS constructor is the same instance as the form where the button was clicked, which is not the case. You have a chicken-and-egg problem. Your form creates a CLASS, and the CLASS creates a form. So now you have two different forms. (or two different CLASS instances since you don't show how the first form or CLASS is created)
You need to "connect" the form and the class, either by passing the form to the constructor as a parameter or by some other means.
Finally, I would encourage you to do some research on best practices for class and member names. It's a bit disconcerting for a seasoned C# developer to see names in all caps and prefaced by underscores.
I am making an app for a friend, and need the user to "input" a value, and return it to the MySQL code I have. this way, what displays will change.
My problem is this: When I do "Form1 newForm = new Form1();" (this is called in DB_Application)
I get a stackoverflow error.
public partial class Form1
{
private DBApplication DB_App = new DBApplication();
private void InitializeComponent()
{
this.orderID.Text = "";
this.orderID.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.EnterKey);
.....
this.phoneNumber.Text = DB_App.phone_number;
.....
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void EnterKey(object o, KeyPressEventArgs e)
{
if(e.KeyChar == (char)Keys.Enter)
{
//converts the "orderID.Text" to an integer value.
if (!int.TryParse(orderID.Text, out newCurrentID))
MessageBox.Show("not a number");
e.Handled = true;
}
}
}
public class DBApplication : DBInfo
{
Form1 newForm = new Form1(); // infinite loop
public DBApplication()
{
OrderID();
}
private string OrderID ()
{
.... //reads the MySQL info, and outputs the value from the database.
}
}
After the User presses "enter" I need the value to go back into "DB_Application" so the MySQL command may receive it, and output a new value.
As mentioned in your comments and by others, the stack overflow is coming from your DBApplication instantiating a Form1, which in turn instantiates a DBApplication, which in turn instantiates a Form1 and so on.
Rewrite your DBApplication to take a Form1 as part of its constructor rather than instantiating its own, this will avoid the infinite recursion and likely this is want you want since the DBApplication will properly reference the open form:
public class DBApplication
{
private Form1 Form;
public DBApplication(Form1 form)
{
this.Form = form;
}
...
}
public partial class Form1 : Form
{
private DBApplication DB_App;
public Form1()
{
DB_App = new DBApplication(this);
InitializeComponent();
}
...
}
Depending on the rest of your application, you may want to instantiate DB_App after the call to InitializeComponent(). (On second look at your code, it's pretty obvious that the DB_App needs to be assigned before calling InitializeComponent().)
Also, since we don't know the full design/usage of DBApplication, perhaps you need to flip it around where the DBApplication instantiates a Form1, and the Form1 has the existing DBApplication passed in instead.
There are generally better ways of doing this (say via dependency injection), but this should be a simple way without completely breaking the architecture you have now.
If you indeed call new Form1() from DBApplication the StackOverflow comes from new DBApplication() in Form1 (it's an instance variable). How to solve the problem depends on your application logic.
I'm trying to write my first program in C# without the use of a tutorial. To ensure that I adopt from the start good coding practices, I want to create each class in an different .cs file. However, I'm running into some troubles when trying to access the elements of the program in such an .cs file.
For example, I have an Form1.cs with an Label and a Start button. When clicking on the start button, a text should appear in the Label. So:
In Form1.cs I have:
namespace TestProgram
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void startButton_Click(object sender, EventArgs e)
{
WriteToLabel message = new WriteToLabel();
message.WelcomeMessage();
}
}
}
And in my separate WriteToLabel.cs file:
namespace TestProgram
{
public class WriteToLabel
{
public void WelcomeMessage()
{
Form1 myForm = new Form1();
//myForm.. --> myForm doesn't have an 'outputLabel'?
outputLabel.Text = "Welcome!"; // This returns an error: 'The name outputLabel does not exits in the current context'.
}
}
}
'outputLabel' is the (Name) I've given the label, and this is in accordance to the name in Form1.Designer.cs.
Both files are using the same components such as 'using System';.
However, from my WriteToLabel.cs file I can't seem to access the Form which holds my program. I did manage to succeed to create different .cs files in an Console Application, which only added to my confusion. So, I have two questions:
First, how can I access the Form from a separate class (i.e. not an partial class) in a separate file?
Second, is this the good way to do it, or is it inefficient to create multiple instances of different classes?
Any thoughts or ideas are highly welcome,
Regards,
The designer automatically creates controls as private fields, because of that your WriteToLabel class can't access it. You need to change that.
Also a good start would be to change the class to something like that:
namespace TestProgram
{
public class WriteToLabel
{
Form1 form;
public WriteToLabel(Form1 form)
{
this.form = form;
}
public void WelcomeMessage()
{
//Form1 myForm = new Form1();
//myForm.. --> myForm doesn't have an 'outputLabel'?
form.outputLabel.Text = "Welcome!";
}
}
}
You're actually instantiating a new instance of Form1, whereas you need to pass in a reference to your existing instance:
public void WelcomeMessage(Form1 form)
{
form.outputLabel.Text = "Welcome";
}
You also need to ensure that outputLabel is a public (or internal) property/field of Form1 so you can set the value accordingly. Then the calling code is slightly different:
private void startButton_Click(object sender, EventArgs e)
{
WriteToLabel message = new WriteToLabel();
message.WelcomeMessage(this);
}
You need to make sure that Form1.outputLabel has public or internal visibility.
You only need something like a LabelWriter class if the class is going to share a significant amount of state or private methods. If all you have is a bunch of methods that set properties on separate objects, you might as well just keep it as a method on the same object (in this case the Form1 object):
void startButton_Click(object sender, EventArgs e)
{
displayWelcomeMessage();
}
void displayWelcomeMessage()
{
this.outputLabel = "Welcome!";
}
I have a simple windows application in C# with 3 forms.
first form is main form (its name is FrmMain), second is FrmData and third is FrmShow.
In main form (FrmMain) I have created an instance from second form (FrmData) and show it :
public partial class FrmMain : Form
{
public Form FrmModifyData; //for FrmData
int PersonCode;
public FrmMain()
{
InitializeComponent();
}
private void btnShowDataForm_Click(object sender, EventArgs e)
{
FrmModifyData= new FrmData();
FrmModifyData.ShowDialog();
}
}
but I can't access from FrmModifyData to FrmMain fields like PersonCode .
How can I access to creator object's field?
Note: I'm a beginner.
thanks.
You would need to add a property to your FrmModifyData class to take an instance of the FrmMain class. Then you can do this:
FrmModifyData = new FrmData();
FrmModifyData.ParentData = this;
FrmModifyData.ShowDialog();
Then inside FrmModifyData you would have access to the public members of FrmMain. Obviously this is kind of quick and dirty and not very reusable so i would suggest adding more explicit properties to FrmModifyData with only the data you need to use.
If you want to access PersonCode field, you should declare it as public. No visibility modifier will make it private, hence not accesible from other casses.
I would make it something like this.
With this way you're able to use the FrmModifyData in other forms.
I know it's an old post, but yes, you did read it :)
public partial class FrmMain : Form
{
// public Form FrmModifyData; <-- do not declare it in your FrmMain
// (is't a modal dialog, so you won't get more instances)
public int PersonCode {get; set;}
public FrmMain()
{
InitializeComponent();
}
private void btnShowDataForm_Click(object sender, EventArgs e)
{
FrmData FrmModifyData = new FrmData();
FrmModifyData.PersonCode = this.PersonCode;
DialogResult result = FrmModifyData.ShowDialog();
if(result == DialogResult.Ok)
{
// do something with the result
this.PersonCode = FrmModifyData.PersonCode;
}
}
}