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
}
}`
Related
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.
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.
I have this class
Account.cs
namespace EasyFtp
{
class Account
{
public String Username;
public String Password;
public String FtpServer;
}
}
and i have MainWindow Form (Main window for my application ) and logForm with 3 textbox and button. I want to log to my ftp server before show my mainwindow , so i have to showdialog my logform and when thus user press button it get all information from logform and pass it to my mainwindow and save data in object of Account class ; my question is how i pass the data.
MainWindow.cs
namespace EasyFtp
{
public partial class MainWindow: Form
{
private Account myaccount;
LogInForm g;
public MainWindow()
{
InitializeComponent();
g = new LogInForm();
g.ShowDialog();
}
/* how i continue the code */
}
}
LogInForm
namespace EasyFtp
{
public partial class LogInForm : Form
{
public LogInForm()
{
InitializeComponent();
}
private void OKButton_Click(object sender, EventArgs e)
{
/*log in code (not created yet)*/
this.Dispose();
}
}
}
Update:
Your Main window
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
textBox1.Text = "original text";
}
private void button1_Click(object sender, EventArgs e)
{
new Form2().ShowDialog();
}
}
Your dialog-form, that will change the values in Form1
public Form2()
{
InitializeComponent();
// Get the text from Form1
textBoxOrg.Text = Application.OpenForms["Form1"].Controls["textBox1"].Text;
}
private void button1_Click(object sender, EventArgs e)
{
// Change the text on Form1
Application.OpenForms["Form1"].Controls["textBox1"].Text = textBox1.Text;
}
You probably wan't to change value on public properties instead of UI-elements.
Another, and cleaner way, is to pass fields to the form with a ref
In my app in several time i have to call a window(class). the work of this window is to show the meaning of a word.when i again call that window a new window shows but the previous one also shows.
I have two form named form1,form2.
Form1 is like that:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
Form2 s = new Form2(a);// it will be called as many time as i click
s.Show();
}
}
Form2 is like that:
public partial class Form2 : Form
{
public Form2(string s)
{
InitializeComponent();
label1.Text = s;
}
}
what i want is that inside form1 if i call form2 it shows but if i call form2 again the previous form2 window will be closed automatically and new form2 window will be shown instead of previous one.
How can i do that????
Here's an example of storing the Form2 reference at class level, as mentioned by the others already:
public partial class Form1 : Form
{
private Form2 f2 = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (f2 != null && !f2.IsDisposed)
{
f2.Dispose();
}
string a = textBox1.Text;
f2 = new Form2(a);
f2.Show();
}
}
I think you should consider using singleton pattern.
You can implement it like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
Form2.ShowMeaning(a);// it will be called as many time as you click
}
}
and Form2
public partial class Form2 : Form
{
private static readonly Form2 _formInstance = new Form2();
private Form2()
{
InitializeComponent();
}
private void LoadMeaning(string s)
{
label1.Text = s;
}
//Override method to prevent disposing the form when closing.
protected override void OnClosing(CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
}
public static void ShowMeaning(string s)
{
_formInstance.LoadMeaning(s);
_formInstance.Show();
}
}
Hope it helps.
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();
}
//...