Basically; Form1 has 2 buttons, Form2 has 1 button.
When you click Form2's button it checks which button on Form1 you clicked, opening Form3 or Form4 depending on which button you clicked (on Form1).
So I've utilized Mark Halls first method of passing variables between forms. Now for the second half of my closed refinement.
Form1
private void btnLogin_Click(object sender, EventArgs e)
{
// Call function while storing variable info.
Account("login");
}
private void btnRegister_Click(object sender, EventArgs e)
{
// Call function while storing variable info.
Account("register");
}
// Function used to pass Variable info to Account form while opening it as instance.
private void Account(string formtype)
{
// Generate/Name new instant of form.
frontend_account frmAcc = new frontend_account();
// Pass variable to instance.
frmAcc.CheckButtonClick = formtype;
// Show form instance.
frmAcc.Show(this);
// Hide this instance.
this.Hide();
}
Form2
// String Variable to store value from Login.
public string CheckButtonClick { get; set; }
private void btnContinue_Click(object sender, EventArgs e)
{
// If statement to open either Main form or Registration form, based on Login variable.
if (CheckButtonClick == "login")
{
// Generate/Name new instant of form.
frontend_main frmMain = new frontend_main();
// Show form instant.
frmMain.Show();
// Close this instant.
this.Close();
}
else if (CheckButtonClick == "register")
{
// Generate/Name new instant of form.
frontend_register frmReg = new frontend_register();
// Show form instant.
frmReg.Show();
// Close this instant.
this.Close();
}
}
On Form2 there are TWO radio buttons, can I adept that code to set the focus of a tab control when a form is opened? ie. if radClient is checked set focus on tabcontrol after opening winform, else if radStudent is checked set focus on tabcontrol (other page) after opening winform... and i guess don't open a winform if no radio is checked.
I believe this will set the focus;
// Sets focus to first tab.
tabRegister.SelectedTab = tabRegister.TabPages[0];
// Sets focus to second tab.
tabRegister.SelectedTab = tabRegister.TabPages[1];
In your example the first problem I see is you are closing your parent form which closes your Form1 and disposes of Your Form2, What I would do is Hide Form1 instead of Closing it, I would then create a public property on Form2 to pass in the Button that was selected. But anytime you are opening and closing multiple Forms it can get messy, what I would do would be to create UserControls for your additional Forms and swap them out in a Panel. The first example is how to do it the way that you asked.
Form
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
ShowForm2("login");
}
private void btnRegister_Click(object sender, EventArgs e)
{
ShowForm2("register");
}
private void ShowForm2(string formtype)
{
Form2 f2 = new Form2(); // Instantiate a Form2 object.
f2.CheckButtonClick = formtype;
f2.Show(this); // Show Form2 and
this.Hide(); // closes the Form1 instance.
}
}
Form2
ublic partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public string CheckButtonClick { get; set; }
private void button1_Click(object sender, EventArgs e)
{
if (CheckButtonClick == "login")
{
Form3 f3 = new Form3(); // Instantiate a Form3 object.
f3.Show(); // Show Form3 and
this.Close(); // closes the Form2 instance.
}
else if (CheckButtonClick == "register")
{
Form4 f4 = new Form4(); // Instantiate a Form4 object.
f4.Show(); // Show Form4 and
this.Close(); // closes the Form2 instance.
}
}
}
Form3 and Form4 note since Form1 is long forgotten to these forms I search for it to Open back up
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void Form3_FormClosed(object sender, FormClosedEventArgs e)
{
FormCollection frms = Application.OpenForms;
foreach (Form f in frms)
{
if (f.Name == "Form1")
{
f.Show();
break;
}
}
}
}
The second Option with UserControls has one Form with a Panel on it. It uses events to signal the Form to Change Controls plus a public property on UserControl2
public partial class Form1 : Form
{
string logonType;
public Form1()
{
InitializeComponent();
}
private void userControl1_LoginOrRegisterEvent(object sender, LoginOrRegisterArgs e)
{
logonType = e.Value;
userControl2.BringToFront();
}
private void userControl2_ControlFinshedEvent(object sender, EventArgs e)
{
if (logonType == "logon")
userControl3.BringToFront();
else if (logonType == "register")
userControl4.BringToFront();
}
private void userControl3_ControlFinshedEvent(object sender, EventArgs e)
{
userControl1.BringToFront();
}
private void userControl4_ControlFinshedEvent(object sender, EventArgs e)
{
userControl1.BringToFront();
}
}
UserControl1
public partial class UserControl1 : UserControl
{
public delegate void LoginOrRegisterHandler(object sender, LoginOrRegisterArgs e);
public event LoginOrRegisterHandler LoginOrRegisterEvent;
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
LoginOrRegisterArgs ea = new LoginOrRegisterArgs("logon");
LoginOrRegisterEvent(sender, ea);
}
private void button2_Click(object sender, EventArgs e)
{
LoginOrRegisterArgs ea = new LoginOrRegisterArgs("register");
LoginOrRegisterEvent(sender, ea);
}
}
public class LoginOrRegisterArgs
{
public LoginOrRegisterArgs(string s) {Value = s;}
public string Value {get; private set;}
}
UserControl2
public partial class UserControl2 : UserControl
{
public delegate void ControlFinishedHandler(object sender, EventArgs e);
public event ControlFinishedHandler ControlFinshedEvent;
public UserControl2()
{
InitializeComponent();
}
public string SetLogonType { get; set; }
private void button1_Click(object sender, EventArgs e)
{
ControlFinshedEvent(sender, new EventArgs());
}
}
UserControl3 & UserControl4 exactly the same except for different Class Name
public partial class UserControl3 : UserControl
{
public delegate void ControlFinishedHandler(object sender, EventArgs e);
public event ControlFinishedHandler ControlFinshedEvent;
public UserControl3()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ControlFinshedEvent(sender, new EventArgs());
}
}
As I suggested in my comment, one of the best way I know to pass data between forms is to use events.
Basically, in the "child" forms, you declare an event that will be handled, or listened to, by the "main" form.
See the referenced answer from my comment, and if you have specific questions on how to adapt it, ask away.
Cheers
Related
I have two forms Form1 and Form2, Form 1 with a dataGridView and a button where Form2 has one button.
When i click the button1 in Form1, it will open Form2 (overlapping).
Now i need to clear the values of the datagridview in Form1 when i press the
button in Form2 also the same button click event should close the
Form2.
Any idea how to do it?
Any help is appreciated
This is Form 2:
private DataGridView _dgv;
public Form2(DataGridView dgv)
{
_dgv = dgv;
InitializeComponent();
}
private void buttonClearRows_Click(object sender, EventArgs e)
{
_dgv.Rows.Clear();
Close();
}
This is Form1:
private void buttonOpenForm2_Click(object sender, EventArgs e)
{
new frm2(dataGridView1).ShowDialog();
}
You need to pass a reference to Form1 into Form2, either by consctructor or by a property. Sample uses constructor. Change the names of the controls to the ones you have. Consider this as a pseudo code sample.
Form1 (some logic removed for brewity)
public class Form1
{
...
public void Clear()
{
DataGridView1.Rows.Clear();
}
public void btnOpenForm2_Click(object sender, EventArgs e)
{
var form2 = new Form2(this); // create a new form2, and pass a reference to form1
form2.Show(); // show the form.
}
...
}
Form2 (some logic removed for brewity)
public class Form2
{
private Form1 _parent; // this will hold the parent until Form2 is disposed.
...
public void Form2(Form1 parent)
{
_parent = parent; // assign Form1 instance to a field.
}
public void btnClearGrid(object sender, EventArgs e)
{
_parent.Clear(); // clear the rows in the datagridview instance within form1.
}
...
}
If I understand what you're asking, I strongly suggest to hide access to DataGridView in Form1 from outside the class, to avoid unexpected behavior in future.
You could instead add a function in Form1 and manage button1 click event in this way:
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
Form2 dialog = new Form2();
dialog.ShowDialog(this);
}
public void ClearRows() { dataGridView1.Rows.Clear(); }
}
Then in Form2 you can easily handle click on button in this way:
public partial class Form2 : Form
{
private void button1_Click(object sender, EventArgs e)
{
((Form1)this.Owner).ClearRows();
this.Close();
}
}
It's very simply, in the form1 you can create an instance of Form2 and after the show you can set the reference of dataGridView in child form2.
Fundamental is who you set the dataGridProperty modifier=public(visual property F4) in the form1
This is Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f = new Form2();
f.dataGridViewPassed = this.dataGridView1;
f.ShowDialog();
}
}
This is Form 2:
public partial class Form2 : Form
{
public DataGridView dataGridViewPassed = null;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.dataGridViewPassed.Rows.Clear();
}
}
I have an application with 2 Forms, for those forms I have create a Menu which I depose on the two forms.
There is only a menuStrip item on the menu, I just want when I click on "test1" to redirect to Form1 and when I click to "test2" I want to redirect to Form2.
But if test1 is already open/display I don't want to show him again and the same for test2.
My code in my Menu :
public partial class Menu : UserControl
{
public Menu()
{
InitializeComponent();
}
private void test1ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
Form2 f2 = new Form2();
f2.Hide();
f1.Hide();
f1.ShowDialog();
}
private void test2ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
Form2 f2 = new Form2();
f1.Hide();
f2.Hide();
f2.ShowDialog();
}
}
My Form1 :
My Form2 :
I just want the same result like my Buttons in Form1 and Form2 :
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
Form1 f1 = new Form1();
f1.ShowDialog();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
Form2 f2 = new Form2();
f2.ShowDialog();
}
}
I thought that the property Visible for forms could help me but not...
The problem is when I click on my buttons it's open a new window but when my form is already open I don't want to open it again.
Thanks for your reply, I hope that I am clear sorry for my english in advance.
You are currently creating a new form each time the click handler code is executed.
Here is one way, but its nasty and I wouldn't really recommend it. I've assumed that form1 is the entry to your application and that its also the exit of the application. This solution uses a singleton to hold the f1/f2 instances.
public static class Global
{
static Global()
{
f2 = new Form2();
}
public static Form f1;
public static Form f2;
}
Your menu altered:
public partial class Menu : UserControl
{
public Menu()
{
InitializeComponent();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
Global.f2.Hide();
Global.f1.Hide();
Global.f1.Show();
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
Global.f1.Hide();
Global.f2.Hide();
Global.f2.Show();
}
public void SetForm1(Form form)
{
Global.f1 = form;
}
public void SetForm2(Form form)
{
Global.f2 = form;
}
}
And the forms:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Global.f1 = this;
}
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
Global.f2.ShowDialog();
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
Global.f1.Show();
}
}
Hope this helps.
Your logic is wrong.
It seems to me that you want to display different content depending on the user selection on that 'menuStrip'. You need to look at dynamic controls loading not different forms loading.
You can have just a MainForm with that 'menuStrip' and a Panel. Define some User Controls and dynamically add them to that panel based on the user selection.
Snippet
public MainForm : Form
{
public MainForm()
{
// code
}
public void MenuStrip_OptionSelected(object sender, EventArgs e)
{
Panel1.Controls.Clear();
switch(MenuStrip.SelectedValue)
{
case "UserControl1" : Panel1.Controls.Add(new UserControl1()); break;
...
}
}
}
public UserControl1 : UserControl
{
// code
}
in my application i have four forms form1 form2 form3 form4 .and each form have two buttons i.e next and previous buttons to switch between forms .and my question is how can i Switch between forms without creating new instance of forms? below is my code
In Form1:
public Form1()
{
InitializeComponents();
}
private void Next_Click(object sender, EventArgs e)
{
this.Hide()
Form2 form2 = new Form2();
form2.Show();
}
In Form2:
public Form2()
{
InitializeComponents();
}
private void Previous_Click(object sender, EventArgs e)
{
this.Hide();
Form1 form1 = new Form1();
form1.Show();
}
private void Next_Click(object sender, EventArgs e)
{
this.Hide();
Form3 form3 = new Form3();
form3.Show();
}
In Form3:
public Form3()
{
InitializeComponents();
}
private void Previous_Click(object sender, EventArgs e)
{
this.Hide();
Form2 form2 = new Form2();
form2.Show();
}
private void Next_Click(object sender, EventArgs e)
{
this.Hide();
Form4 form4 = new Form4();
form4.Show();
}
In Form4:
public Form4()
{
InitializeComponents();
}
private void Previous_Click(object sender, EventArgs e)
{
this.Hide();
Form3 form3 = new Form3();
form3.Show();
}
In Main:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
In above code i am creating new instances of forms every time..,How can i Avoid this and How can i Switch between forms without creating new instances of forms.... please help me
Since you are accessing your forms sequentially just make sure that you use the Show Method that assigns the owner to the created Form and assign it to a class level variable after you create it. Something like this should work for you.
Form1
public partial class Form1 : Form
{
Form2 frm2;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (frm2 == null)
{
frm2 = new Form2(); //Create form if not created
frm2.FormClosed += frm2_FormClosed; //Add eventhandler to cleanup after form closes
}
frm2.Show(this); //Show Form assigning this form as the forms owner
Hide();
}
void frm2_FormClosed(object sender, FormClosedEventArgs e)
{
frm2 = null; //If form is closed make sure reference is set to null
Show();
}
}
Form2
public partial class Form2 : Form
{
Form3 frm3;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Owner.Show(); //Show the previous form
Hide();
}
private void button2_Click(object sender, EventArgs e)
{
if (frm3 == null)
{
frm3 = new Form3();
frm3.FormClosed += frm3_FormClosed;
}
frm3.Show(this);
Hide();
}
void frm3_FormClosed(object sender, FormClosedEventArgs e)
{
frm3 = null;
Show();
}
}
Form3
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Owner.Show();
Hide();
}
}
May be a easy solution. You can make a class that contains static object of all forms that you need. So you will be able to access all these forms from any forms of your choice and the good thing is they are initialized once.
public class formList
{
private static Form1 _form1 = new Form1();
public static Form1 form1 { get {return _form1;}
.................
............
}
Try This:
Form1 myForm =(Form1) Application.OpenForms["Form1"];
myForm.Show();
You can check if the form of interest exists, and if not create it:
public static T OpenOrCreateForm<T>()
where T: Form, new() {
T result;
// Test if form exists
foreach(Form form in Application.OpenForms) {
result = form as T;
if (!Object.ReferenceEquals(null, result)) {
// Form found; and this is the right place
// to restore form size,
// bring form to front etc.
if (result.WindowState == FormWindowState.Minimized)
result.WindowState = FormWindowState.Normal;
result.BringToFront();
return result;
}
}
// Form doesn't exist, let's create it
result = new T();
// Probably, you want to show the created form
result.Show();
resturn result;
}
...
private void Previous_Click(object sender, EventArgs e)
{
Hide();
OpenOrCreateForm<Form1>();
}
private void Next_Click(object sender, EventArgs e)
{
Hide();
OpenOrCreateForm<Form3>();
}
public bool IsFormAlreadyOpen(Type FormType)
{
foreach (Form OpenForm in Application.OpenForms)
{
if (OpenForm.GetType() == FormType)
return true;
}
return false;
}
This function can be used to find out whether a form is already opened or not
call IsFormAlreadyOpen(Form4) if it returns true which means Form4 is already opened
and in your case
in every forms constructor() create next and previous forms object
and in the button click calls IsFormAlreadyOpen() to find out whether the form is already opened or not and if it already opened just bring that form in front
other wise display the form using obj.show() method
and hide or close the parent form
Looks like you are trying to achieve wizard like feature. I would recommend having a single form. Then, add a customized tab control to it. Add buttons to form that moves previous and next.
To customize tab control, this is what you need to do:
public class CustomWizard : TabControl
{
/// <summary>
/// This method traps windows message and hides other tabs in the tab control.
/// Message trapped: TCM_ADJUSTRECT
/// </summary>
/// <param name="m">Reference to Windows message</param>
protected override void WndProc(ref Message m)
{
// Second condition is to keep tab pages visible in design mode
if (m.Msg == 0x1328 && !DesignMode)
{
m.Result = (IntPtr)1;
}
else
{
base.WndProc(ref m);
}
}
/// <summary>
/// This method traps the press to stop users from selecting tab page via keyboard
/// </summary>
/// <param name="ke">Event details</param>
protected override void OnKeyDown(KeyEventArgs ke)
{
if (ke.Control && ke.KeyCode == Keys.Tab)
return;
base.OnKeyDown(ke);
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
This tab control will only display one tab at a time. Although, at design time you can see them all. Add this and buttons to your form. On button click, merely set the SelectedIndex property of this tab control.
I had the same issue. An application I needed that had many forms and I needed to switch between forms forward n backward without losing the data. I came up with the following solution and it worked for me.
In the main (Program.cs) file, write the following two classes:
static class Variables
{
public static DataSet Configurations = new DataSet();
public static float ExchangeRate = 0;
public static Dictionary<string, int> ItemsCategories = new Dictionary<string, int>();
public static Dictionary<string, float> WeightUnits = new Dictionary<string, float>();
}
static class Forms
{
public static Form2 F_Form2 = new Form2();
public static Form3 F_Form3 = new Form3();
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
The first class is used for Global variables that can be used across the forms. You can access any variable by:
Variables.ExchangeRate = 7.2; //(for ex).
The second class is where you define new instance of all your forms. You can hide n show them anywhere across all the forms by:
Forms.F_Form3.Show();
or
Forms.F_Form2.Hide();
This works smoothly and perfect for me. Try it.
Just remove the this.hide() in the first form and the [formNameHere].show(); in the second form.
Like this:
Form 1:
public Form1()
{
InitializeComponents();
}
private void Next_Click(object sender, EventArgs e)
{
this.Hide()
Form2 form2 = new Form2();
form2.Show();
}
Form 2:
public Form2()
{
InitializeComponents();
}
private void Previous_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
this.Hide();
}
private void Next_Click(object sender, EventArgs e)
{
Form3 form3 = new Form3();
this.Hide();
}
etc.. not good at explaining, and with C# really. But this should work.
//In Form1
private static Form1 i_Instance = null;
public static Form1 Instance
{
get
{
if (Form1.i_Instance == null) Form1.i_Instance = new Form1();
return Form1.i_Instance;
}
}
// And instantiation in other forms shall look like following
Form1 F1 = Form1.Instance;
F1.Show();
This question is the followup to the following question:
C# Text don't display on another form after double clicking an item in listbox
Now I have typed my value in the textbox of form3. How am I going to pass back the value to form1 to show it in the listbox10 after pressing "OK" in form3? Below is my form3 coding but it don't work:
private void button1_Click(object sender, EventArgs e)
{
//This is the coding for "OK" button.
int selectedIndex = listBox10.SelectedIndex;
listBox10.Items.Insert(selectedIndex, textBox1.Text);
}
You can put public property on form3:
public partial class form3 : Form
{
public String SomeName
{
get
{
return textbox1.Text;
}
}
...
private void buttonOK_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
In form1, where you are open form3, after ShowDialog, you will write:
if (form3.ShowDialog() == DialogResult.OK)
{
int selectedIndex = listBox10.SelectedIndex;
if (selectedIndex == -1) //listbox does not have items
listbox10.Add(form3.SomeValue);
else
listBox10.Items.Insert(selectedIndex, form3.SomeName);
}
do do something like that:
//form1:
public void add(int num)
{
//add num to the list box.
}
now, form3 should get an instance of form1 in the constructor, and save it:
//in form3:
private form form1_i
public form3(form i_form1)
{
.
.
.
form1_i = i_form1;
}
and on button click in form3, call the fumction add in form1.
It should go like this, this is the safest way to do it, in fact if you are working on Windows Mobile this is the only way that won't crash the application. In desktop versions it can crash in debug versions.
public partial class Form1 : Form
{
public string name = "something";
public Form1()
{
InitializeComponent();
}
public delegate void nameChanger(string nme);
public void ChangeName(string nme)
{
this.name = nme;
}
public void SafeNameChange(string nme)
{
this.Invoke(new nameChanger(ChangeName), new object[] { nme });
}
private void button2_Click(object sender, EventArgs e)
{
Form3 f3 = new Form3(this);
f3.Show();
}
}
public partial class Form2 : Form
{
Form1 ff;
public Form2(Form1 firstForm)
{
InitializeComponent();
ff = firstForm;
}
private void button2_Click(object sender, EventArgs e)
{
ff.SafeNameChange("something different from the Form1");
this.Close();
}
}
I know how to go to another form in modal mode just like what I did below:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Form2 myNewForm = new Form2();
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
myNewForm.ShowDialog();
}
}
This is my second form, how do I go back to the previous form?
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
// what should i put here to show form1 again
}
}
When you call ShowDialog on a form, it runs until the form is closed, the form's DialogResult property is set to something other than None, or a child button with a DialogResult property other than None is clicked. So you could do something like
public partial class Form1
{
...
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
newform.ShowDialog();
// We get here when newform's DialogResult gets set
this.Show();
}
}
public partial class Form2
{
...
private void button1_Click(object sender, EventArgs e)
{
// This hides the form, and causes ShowDialog() to return in your Form1
this.DialogResult = DialogResult.OK;
}
}
Although if you're not doing anything but returning from the form when you click the button, you could just set the DialogResult property on Form2.button1 in the form designer, and you wouldn't need an event handler in Form2 at all.
I use a static Form value Current in all my multiple form apps.
public static Form1 Current;
public Form1()
{
Current = this;
// ... rest of constructor
}
Then in Form2
public static Form2 Current;
public Form2()
{
Current = this;
// ... rest of constructor
}
Then you can from your button click do,
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
// what should i put here to show form1 again
Form1.Current.ShowDialog(); // <-- this
}