How to get access to parent form? - c#

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.

Related

Calling method / refreshing data in another form

So I have 2 forms - frmMain and frmChild
The frmChild form is declared as I run frmMain
frmChild form1 = new frmChild();
I also have a button that runs a method to open the frmChild form.
OpenForm(form1);
The question is, how can I update data / call desired method on the frmChild form while I'm still on the frmMain form? I need to do it on the existing instance of the form, without creating a new one.
I've tried doing it this way, but can't access the method
The frmMain class
public partial class frmMain: DevExpress.XtraEditors.XtraForm
{
frmChild form1 = new frmChild();
private void UpdateDataOnChildForm()
{
form1.UpdateData(); // cant access this method...
}
}
The frmChild class
public partial class frmChild : DevExpress.XtraEditors.XtraForm
{
public void UpdateData()
{
//update data here...
}
}
any tips will be appreciated
public partial class frmMain : Form
{
private frmChild form1 = new frmChild();
private DoSomeActionOnfrmChild()
{
form1.SomeAction();
}
}
public partial class frmChild : Form
{
public void SomeAction()
{}
}
`public partial class MainForm : Form
{
private void btnMain_Click(object sender, EventArgs e)
{
LoginForm lfrm = new LoginForm;
LoginForm.ShowDialog();
}
private void SecureMethod(){//do sth};
}
public partial class LoginForm : Form
{
private void btnok_Click(object sender, EventArgs e)
{
SecureMethod(); //is not true
this.close(); //close loginform
}
}`

Calling a function from another form c#

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.

How to call a function from another form

this is probably one of the most common question out there, having a FORM1 and FORM2, how I can call a function (on FORM1) like: MySQLConnect from FORM2. I tried couple of options and I can't get it to work, in the second attempt I tried calling the function from a button, but no luck.
Form1.cs (My first attempt:)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Form2 form2 = new Form2(this);
}
public void MySQLConnect(object sender, EventArgs e)
{
// Starting a MySQL connection
}
}
Form2.cs (My first attempt:)
public partial class Form2 : Form
{
Form1 mainForm;
public Form2(Form1 mainForm)
{
InitializeComponent();
this.mainForm = mainForm;
// call function on form1 MySQLConnect()
mainForm.MySQLConnect();
}
}
Form1.cs (My Second attempt:)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void MySQLConnect(object sender, EventArgs e)
{
// Starting a MySQL connection
}
}
Form2.cs (My Second attempt:)
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void btnMySQLConnect(object sender, EventArgs e)
{
Form1 myForm1 = new Form1();
myForm1.MySQLConnect(sender, e);
}
}
Please help!
Your first example works if you pass the parameters expected by MySqlConnect.
public partial class Form2 : Form
{
Form1 mainForm;
public Form2(Form1 mainForm)
{
InitializeComponent();
this.mainForm = mainForm;
mainForm.MySQLConnect(this, new EventArgs());
}
}
However, I can't imagine what a function named MySqlConnect could do with the parameters passed.
So it is better to remove them in the method definition and do not pass anything when you call it.
And I agree with the comments above. Why do you hide such important (and often required functionality) inside a Form instance? You have to pass this form instance everywhere you need to connect to your database. It is better to prepare some static service class ( in a Database Access Layer) that carry on this job
mainForm.MySQLConnect();
public void MySQLConnect(object sender, EventArgs e)
Any ideas? You just omitted arguments.

Pass a variable from an open form C#

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;}
}

How to access a form control for another form?

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();
}
//...

Categories