i have a main form with a function that changes the text of a text box thats on the main form, the code is below:
main form function:
public void consoleLog(string message)
{
txtConsoleLog.Text += Environment.NewLine;
txtConsoleLog.Text += message;
txtConsoleLog.SelectionStart = txtConsoleLog.TextLength;
txtConsoleLog.ScrollToCaret();
txtConsoleLog.Refresh();
}
So now i open a new form called frm connect when i click a button like this:
private void connectToolStripMenuItem_Click(object sender, EventArgs e)
{
Form frmConnect = new FrmConnect(this);
frmConnect.Show();
}
this is the frmConnect below
public partial class FrmConnect : Form
{
private Form mainForm;
public FrmConnect(Form frmMain)
{
this.mainForm = frmMain;
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
FrmMain.Connected = true;
mainForm.consoleLog("Connected");
}
}
So when i click a button i want to call the function but its saying it doesnt contain a definition for it, also im trying to change the 'Connected' variable thats on the main form which works by just referencing the FrmMain but am i able to do that using mainForm.Connected = true?
If i change the function to public static, it will work by referencing FrmMain but then i get errors with the txtConsoleLog as i cant reference an object in a non static method or something like that, any help is appriciated
When you pass the form into your constructor, and store it as the private member variable, in both places you declare it of the base type Form. In order to use a method on the type that you defined, your parameter and variable should be of type FrmMain.
public partial class FrmConnect : Form
{
private FrmMain mainForm;
public FrmConnect(FrmMain frmMain)
{
this.mainForm = frmMain;
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
FrmMain.Connected = true;
mainForm.consoleLog("Connected");
}
}
You should change
private Form mainForm;
public FrmConnect(Form frmMain)
{
To
private FrmMain mainForm;
public FrmConnect(FrmMain frmMain)
{
which will later give you access to all of the public properties on FrmMain in your other methods in the FrmConnect class.
Related
Maybe you can help me with my problem.
My Class "Form1" calls the method setButtons();
but setButtons() ist not at Class "Form1", its in Class "Class1".
setButtons() in "Class1" does not recognice Button1 from Form1.
How do I let it know that Button1 exists in Form1 and I want the method to work on the Button1 from "Form1"? Class1 has already a using directory to Form1 and Form1 has one to Class1.
//this does not work
public static void setbuttons()
{
Form1.Button1.Location = new Point(40, 40);
}
I found out that if you declare a control public in the designer file like so
public Button button1;
Then you can access it from another class on the condition that you get the form object, for example as a extension
static class AnotherClass
{
public static void setButtons(this Form1 form)
{
form.button1.Text = "Hello";
}
}
A better way to change the properties of a button, in terms of design and code management, would be to make a method in your form that does it.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
...
}
public void ChangeButtonTextMethod(string text)
{
button1.Text = text;
}
}
Consider using an event where the method in Class1 passes a Point to the calling form which listens for the event, in this case SetButtons.
public class Class1
{
public delegate void OnSetLocation(Point point);
public static event OnSetLocation SetButtonLocation;
public static void SetButtons()
{
SetButtonLocation!(new Point(40, 40));
}
}
In the form subscribe to SetButtonLocation, invoke the method SetButtons which passes a Point to the caller in Form1 and in turn sets the button Location.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Class1.SetButtonLocation += OnSetButtonLocation;
Class1.SetButtons();
Class1.SetButtonLocation -= OnSetButtonLocation;
}
private void OnSetButtonLocation(Point point)
{
button1.Location = point;
}
}
Using this approach is better than changing the modifers of form to public as mentioned already.
I have two Windows Form in project C#.
public partial class Form1 : Form
{
public void add(){
//
}
}
public partial class FormAdd : Form
{
//
}
In Form1 after button click I open FormAdd:
var form = new FormAdd();
form.Show();
After in FormAdd I try to call parent method add:
Form1 f = new Form1();
f.add();
But I can not get access to any methods and properties of parent form.
I get error:
One approach is to pass Form1 in as the Owner of your FormAdd instance in the Show() call:
public partial class Form1 : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
var form = new FormAdd();
form.Show(this); // pass this instance of Form1 in as the Owner of our FormAdd instance
}
}
Now, over in FormAdd, cast the Owner property to Form1 and call add():
public partial class FormAdd : Form
{
private void button1_Click(object sender, EventArgs e)
{
if (this.Owner is Form1)
{
Form1 f1 = (Form1)this.Owner;
f1.add();
}
}
}
Based on your picture, try to add the code above one bracket. Since the error seems to be on the scope of your condition.
This should look like this:
else
position = 0;
//{ <-- Remove this and put it below
if (this.Owner is Form1)
{
//TODO:
}
} //This should be here
Everything should compile properly after that.
I have two forms, Form1 and Form2. Form1 has a variable int x. When the program is executed, Form1 is hidden and Form2 is shown; however i need to call the variable from the existing Form1.
I know the method to call the variable by calling a new instance of Form1.
Form1 r = new Form1();
r.x = 20;
But I want to know how to do it for an already opened Form1.
Take several cases, like if there are multiple variables that are called from Form1, by several forms (Form2, Form3, Form4 etc...). Any variable can be called from Form1 by the forms. Also, forms can call variables from other forms (Like if Form1 and Form2 is open, then Form3 can call variables from Form1 AND Form2)
I know its a huge list, but would really appreciate if anyone can find a good way to implement it.
You will have to have a reference to the "already opened" form1 instance, so that you can reference the value of x on that form.
So, lets say that Form2 instantiates the hidden form1. You will have to have a reference in form2 to the form1, to reference the variable.
OK, Lets say this is the code for form2
public partial class Form2 : Form
{
private Form1 f;
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
f = new Form1
{
Visible = false
};
int x = f.X;
}
}
and then code for form1
public partial class Form1 : Form
{
public int X { get; set; }
public Form1()
{
InitializeComponent();
X = 20;
}
}
and you need to ensure that the form luanched from the program class is
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form2());
}
}
You can do it in following ways,
in my case form1 is form4 and form2 is form5. please consider, :)
//code on form4:
// this is by passing the reference of the form to other form
public partial class Form4 : Form
{
public int a { get; set; }
public int b { get; set; }
public Form4()
{
InitializeComponent();
}
private void Form4_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
a = 5;
b = 6;
Form5 frm5 = new Form5();
frm5.frm4 = this;
this.Close();
frm5.Show();
}
}
// code on form5
public Form4 frm4 { get; set; }
private void Form5_Load(object sender, EventArgs e)
{
int x = frm4.a;
int y = frm4.b;
}
Also you can have a class file in which the instance of the form1 will be static, so that you can use that instance on form2 to refer to the form1's properties.
Let me know, if it does not solve your problem.
I hope it will help you. :)
Create a public property on the form itself. Have the get accessor return the form value. You can call it like this. Form1.MyProperty;
public string MyPrperty {
get {
return Form1.txtExample.text;
}
}
EDIT:
You can return a dictionary of all of those values if you have that many to return at a time. I would seriously consider rethinking your form if you have 20-40 values being filled. That sounds like a poor user experience to me.
i think there is a reason that you wouldn't try System.Properties.Settings.Default
accessible from Project Menu --> Properties in visual studio...
Thanks...
My guess is that you are looking for System.Windows.Forms.Application.OpenForms property which holds all the open forms in an array.
What you need to do is to check the type of each form and if it is equivalent to Form1 access the variable's value. Also, to access the variable outside the form you need to set its access modifier to either Public or make a corresponding property for it.
EDIT
Here is a sample code: (untested)
public partial class Form1 : Form
{
public int X;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
X = 100;
Form2 frm = new Form2();
frm.Show();
this.Hide();
}
}
public partial class Form2 : Form
{
int local_X = 0;
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
foreach(Form f in System.Windows.Forms.Application.OpenForms)
{
if(typeof(f) == typeof(Form1))
{
local_X = f.X; // access value here and set in local variable
}
}
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Value of X is : " + local_X); // Show alert for value of variable on button click
}
}
EDIT
Or you can use constructor overloading to accomplish this task:
public partial class Form1 : Form
{
public int X;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
X = 100;
Form2 frm = new Form2(x); // pass variable to form2, if multiple values pass int array
frm.Show();
this.Hide();
}
}
public partial class Form2 : Form
{
int local_X = 0;
public Form2()
{
InitializeComponent();
}
// Overloading of constructor
public Form2(int X) // if multiple values pass int array
{
InitializeComponent();
local_X = x; // capture value from constructor in class variable.
}
private void Form2_Load(object sender, EventArgs e)
{
// no need to iterate here for now due to overloading value get passed during initialization.
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Value of X is : " + local_X); // display value if alert box.
}
}
Let's look at the situation.You have multiple forms in your application and you want to do access several variables these forms.
My guess is,
public static class GlobalVariables
{
public static object MyVariable1 { get; set; }
public static object MyVariable2 { get; set; }
}
So you can access variables everywhere in your project.
It doesn't matter whether which form is opened or closed. Your ultimate goal is to access a member from Form1 in Form2 isn't it? If that is the case when you create an instance of your Form2, do it like this
Form1 objForm1 = new Form1();
Form2 obj = new Form2(objForm1);
so that in form 2 class looks like this
class Form2: Form
{
private Form1 form1Object;
public Form2(Form1 obj)
{
form1Object = obj;
}
private void SomeMethodInForm2()
{
//Here you can access the variable in form1 like
form1Object.PropertyNameYouWantToAccess;
}
}
The form 1 class can look like this
class Form1: Form
{
public int PropertyNameYouWantToAccess{get;}
}
Well here is the thing, I have MainForm that call OrderForm.Show().
Now I want to call public function in MainForm with a button, but I cant.
Here is the code in MainForm:
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
// Main form
private void MainFrm_Load(object sender, EventArgs e)
{
FormOrder frmO = new FormOrder();
frmO.Show();
}
public void Refresh()
{
// some action
}
}
And in OrderForm I do this:
public partial class FormOrder : Form
{
public FormOrder()
{
InitializeComponent();
}
private void ShowForm()
{
// some action
}
private void btnCopy_Click(object sender, EventArgs e)
{
Form form = Form.ActiveForm as frmMain;
if (form != null)
{
form.Refresh();
}
}
}
so in the Program I run MainForm.Show() then load OrderForm. Then I when I click Copy button, it will run Public Function Refresh in MainForm. But I cant make it work, it always return null in:
Form form = Form.ActiveForm as frmMain;
so how can I actually get the active form, is it another solution? or I get it wrong??
Thanks in advance for the answer :)
You're getting a null because your active form is the one you're in and it is not of type frmMain. (I think you may actually be confusing an active form for a parent form?)
There are so may ways to do this. You could make your frmMain a singleton but that's weird and ugly and not recommended of late or you could pass a reference of it to its children somehow. Here's one, simple way:
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
// Main form
private void MainFrm_Load(object sender, EventArgs e)
{
FormOrder frmO = new FormOrder(this); // pass a ref of self
frmO.Show();
}
public void Refresh()
{
// some action
}
}
And in OrderForm:
public partial class FormOrder : Form
{
private frmMain _parent; // create a field that refers to the parent
public FormOrder(frmMain parent) // mod the constructor
{
if (parent == null) throw new NullReferenceException("Can't be NULL!!!"); // check clause
_parent = parent; // assign the ref of the parent
InitializeComponent();
}
private void ShowForm()
{
// some action
}
private void btnCopy_Click(object sender, EventArgs e)
{
_parent.Refresh(); // make the call to parent
}
}
You could make this better by using an interface but the general idea would be the same.
I would not suggest you take the route to access the active form to accomplish your target. What you need to do is to pass a reference of the MainForm to the OrderForm, so OrderForm could use the reference to call any method on the MainForm.
private void MainFrm_Load(object sender, EventArgs e)
{
FormOrder frmO = new FormOrder();
frmO.MainForm = this;
frmO.Show();
}
And in FormOrder class you should add a new attribute MainForm, and use the attribute to reference the calling form :-
public partial class FormOrder : Form
{
public Form MainForm;
public FormOrder()
{
InitializeComponent();
}
private void ShowForm()
{
// some action
}
private void btnCopy_Click(object sender, EventArgs e)
{
if (MainForm != null)
{
MainForm.Refresh();
}
}
}
You need to have a reference to the mainForm and/or mainForm's button click event that lives outside of mainForm. You can do this is in various ways. Create a static class that has a reference to mainForm, create a static class that has a delegate to the mainForm click event, pass mainForm into the contructor for childForm, pass in a delegate to mainForms click event to the the constructor for the childForm. Create a static method that handles the click event then use that from within childForm.
It really all depends upon what you want to to do, what you need to do, and how you desire to do it.
While the other answers are absolutely correct, I'd like to suggest a much easier yet "dirty" way to do it.
Every component has a Tag property where you can store any user-defined value or reference in. The idea is to save a reference to the main form in the second form's Tag, and access it from the button click event handler.
The good thing is that you do not have to write a lot of code, or create any data structure.
The dirty thing about it is that neither the framework at runtime nor the compiler at compile-time have any idea what you store in .Tag, and since it is not typed correctly, you are doing a type cast, depending on you storing the correct value there beforehand.
If you store the wrong value there, you might have a hard time debugging the cause since the symptom does not signal where you put the wrong value into Tag. So wild Tag usuage in a team of programmers is a good thing if you want to give birth to many unexpected hard-to-detect-and-fix bugs :)
Also, there is only one Tag per component. If you need more than one user-defined value, you might end up creating a custom data structure which Tag then holds a reference to, but that probably is a bigger mess than all of the other suggestions.
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
// Main form
private void MainFrm_Load(object sender, EventArgs e)
{
FormOrder frmO = new FormOrder();
frmO.Tag=this;
frmO.Show();
}
public void Refresh()
{
// some action
}
}
public partial class FormOrder : Form
{
public FormOrder()
{
InitializeComponent();
}
private void ShowForm()
{
// some action
}
private void btnCopy_Click(object sender, EventArgs e)
{
Form form = Tag as frmMain; // form now references the main form
if (form != null)
{
form.Refresh();
}
}
}
A good example for a quick and dirty solution, with limitations so inherent that you usually identify them only when it is too late -- that's why I am telling in the first place ;)
I have two Form classes, one of which has a ListBox. I need a setter for the SelectedIndex property of the ListBox, which I want to call from the second Form.
At the moment I am doing the following:
Form 1
public int MyListBoxSelectedIndex
{
set { lsbMyList.SelectedIndex = value; }
}
Form 2
private ControlForm mainForm; // form 1
public AddNewObjForm()
{
InitializeComponent();
mainForm = new ControlForm();
}
public void SomeMethod()
{
mainForm.MyListBoxSelectedIndex = -1;
}
Is this the best way to do this?
Making them Singleton is not a completely bad idea, but personally I would not prefer to do it that way. I'd rather pass the reference of one to another form. Here's an example.
Form1 triggers Form2 to open. Form2 has overloaded constructor which takes calling form as argument and provides its reference to Form2 members. This solves the communication problem. For example I've exposed Label Property as public in Form1 which is modified in Form2.
With this approach you can do communication in different ways.
Download Link for Sample Project
//Your Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(this);
frm.Show();
}
public string LabelText
{
get { return Lbl.Text; }
set { Lbl.Text = value; }
}
}
//Your Form2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private Form1 mainForm = null;
public Form2(Form callingForm)
{
mainForm = callingForm as Form1;
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
this.mainForm.LabelText = txtMessage.Text;
}
}
(source: ruchitsurati.net)
(source: ruchitsurati.net)
Access the form's controls like this:
formname.controls[Index]
You can cast as appropriate control type, Example:
DataGridView dgv = (DataGridView) formname.Controls[Index];
I usually use the Singleton Design Pattern for something like this http://en.wikipedia.org/wiki/Singleton_pattern . I'll make the main form that the application is running under the singleton, and then create accessors to forms and controls I want to touch in other areas. The other forms can then either get a pointer to the control they want to modify, or the data in the main part of the application they wish to change.
Another approach is to setup events on the different forms for communicating, and use the main form as a hub of sorts to pass the event messages from one form to another within the application.
It's easy, first you can access the other form like this:
(let's say your other form is Form2)
//in Form 1
Form2 F2 = new Form2();
foreach (Control c in F2.Controls)
if(c.Name == "TextBox1")
c.Text = "hello from Form1";
That's it, you just write in TextBox1 in Form2 from Form1.
If ChildForm wants to access the ParentForm
Pass ParentForm instance to the ChildForm constructor.
public partial class ParentForm: Form
{
public ParentForm()
{
InitializeComponent();
}
public string ParentProperty{get;set;}
private void CreateChild()
{
var childForm = new ChildForm(this);
childForm.Show();
}
}
public partial class ChildForm : Form
{
private ParentForm parentForm;
public ChildForm(ParentForm parent)
{
InitializeComponent();
parentForm = parent;
parentForm.ParentProperty = "Value from Child";
}
}
There is one more way, in case you don't want to loop through "ALL" controls like Joe Dabones suggested.
Make a function in Form2 and call it from Form1.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public void SetIndex(int value)
{
lsbMyList.SelectedIndex = value;
}
}
public partial class Form1 : Form
{
public Form2 frm;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
frm=new Form2();
frm.Show();
}
private void button1_Click(object sender, EventArgs e)
{
frm.SetIndex(Int.Parse(textBox1.Text));
}
}
Here's also another example that does "Find and Highlight". There's a second form (a modal) that opens and contains a textbox to enter some text and then our program finds and highlights the searched text in the RichTextBox (in the calling form). In order to select the RichTextBox element in the calling form, we can use the .Controls.OfType<T>() method:
private void findHltBtn_Click(object sender, EventArgs e)
{
var StrBox = _callingForm.Controls.OfType<RichTextBox>().First(ctrl => ctrl.Name == "richTextBox1");
StrBox.SelectionBackColor = Color.White;
var SearchStr = findTxtBox.Text;
int SearchStrLoc = StrBox.Find(SearchStr);
StrBox.Select(SearchStrLoc, SearchStr.Length);
StrBox.SelectionBackColor = Color.Yellow;
}
Also in the same class (modal's form), to access the calling form use the technique mentioned in the #CuiousGeek's answer:
public partial class FindHltModalForm : Form
{
private Form2 _callingForm = null;
public FindHltModalForm()
{
InitializeComponent();
}
public FindHltModalForm(Form2 CallingForm)
{
_callingForm = CallingForm;
InitializeComponent();
}
//...