Passing updating listbox to other form - c#

As the title, i know that many people asked this kind of questions. I have read manys, i success in passing the items in listbox to other form, but in case listbox is adding many new items, i don't know how.
The listbox only update when i reopen the form. This is my code. My way to open new form is modified the Program.cs cuz the listbox is non-static
.....
static class Program
{
private static Lm f1; //This is my Main form
private static Form1 f2; // This is the second
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
f1 = new Lm();
f1.VisibleChanged += OnLmChanged;
Application.Run(f1);
}
static void OnLmChanged(object sender, EventArgs args)
{
if (!f1.Visible)
{
f2 = new Form1(f1.listBox2, f1.listBox3, f1.label7);
f2.Show();
f2.FormClosing += OnFormChanged;
}
}
static void OnFormChanged(object sender, EventArgs args)
{
f1.Show();
}
My code on the second form (Form1)
public partial class Form1 : Form
{
public Form1(ListBox listBox, ListBox list1, Label ll)
{
InitializeComponent();
listBox2.Items.AddRange(listBox.Items);
//listBox.SelectedIndexChanged += (s, args) => //This didn't work
//{
//listBox2.Refresh();
//listBox2.Items.AddRange(listBox.Items);
//};
}
I realize that i shouldn't put the "listBox2.Items.AddRange" in public Form1(..) but i don't know how.. :(
(listBox2 is updating in Lm Form, i'm trying to passing it to Form1 Form)

What does "in public Form1" mean? Do you mean the constructor? The constructor is actually a very good place for initialization. In fact, that's exactly what they were invented for. You've put that code where it belongs, but you can and should improve the way it's written.
What's not so good is passing a listbox to the constructor as a parameter, when all the constructor wants is a collection of items. Maybe the collection you're providing this time happens to belong to a listbox, but that's not important. The same goes for the label text: All Form1 really wants is some text. It doesn't care if the text came from a label somewhere. So have it ask for just the text.
So just pass the items:
public Form1(System.Collections.IEnumerable items,
System.Collections.IEnumerable otherItems,
String labelText)
{
InitializeComponent();
listBox2.Items.AddRange(items);
// etc.
}
And call it like so
static void OnLmChanged(object sender, EventArgs args)
{
if (!f1.Visible)
{
f2 = new Form1(f1.listBox2.Items, f1.listBox3.Items, f1.label7.Text);
f2.Show();
f2.FormClosing += OnFormChanged;
}
}
It would be good to give listBoxItems and otherListboxItems much more specific and descriptive names, but you've provided no information about what the listboxes mean. listBox1 and listBox2 communicate nothing about what's in the listboxes or what purpose they serve in the user interface. That's very bad programming practice. A year from now if you come back to fix this code, you will not know at a glance what this is doing:
listBox2.Items.AddRange(items);
listBox3.Items.AddRange(otherItems);
This, however, actually tells you something:
recipeListBox.Items.AddRange(recipes);
ingredientListBox.Items.AddRange(ingredients);
Maybe it's cars or animals or zipcodes instead of recipes. The same principle applies. It would be easy to get items and otherItems mixed up as to which is which. It's much harder to mix up recipes and ingredients.

Related

C# Get variable from popup form that will be closed

I have a form populated with an array of userControls that is created from the main form. I need to be able to access this array of userControls from the main form once the popup has been closed when a button is pressed. If I fill out the forms and then press the button on the main form without closing the popup, the values are present. However, if I close the popup window, the values are not present. My main form is static so I can use it's variables in other forms.
Code for the popup:
public ScanChannel[] controls;
public ScanListSetup()
{
InitializeComponent();
int numChans = Convert.ToInt32(Form1.Self.numChannels.Text);
controls = new ScanChannel[numChans];
// Create the UserControls
for(int i = 0; i < numChans; i++)
{
controls[i] = new ScanChannel();
}
// Place them
for (int i = 0; i < numChans; i++)
{
controls[i].Location = new Point(13,(35+25*(i)));
this.Controls.Add(controls[i]);
}
doneButton.Location = new Point(82, 35 + (25 * (numChans + 1)));
this.Size =new Size(280, 110 + (25 * (numChans + 1)));
}
private void doneButton_Click(object sender, EventArgs e)
{
Form1.Self.setChannelsToScan(controls);
}
I need to access the controls array in the main form. The code for the main form is as follows:
private ScanChannel[] channelsToScan;
private void configureScanListButton_Click(object sender, EventArgs e)
{
var form = new ScanListSetup();
form.Show(this);
scanListConfigured = true;
this.channelsToScan = new ScanChannel[Convert.ToInt32(numChannels.Text)];
}
public void setChannelsToScan(ScanChannel[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
this.channelsToScan[i] = arr[i];
}
}
private void scanButton_Click(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Test: " + this.channelsToScan[0].getDeviceType());
// THIS PRINTS AN EMPTY STRING
}
So, the Debug writeLine outputs the correct value if I click the scanButton while the popup form is still open. However, if I close the form after clicking the doneButton on the popup form, the Debug writeLine outputs Test: with nothing else.
Any help with this would be greatly appreciated. Thanks.
Your problem essentially boils down to sending data from a secondary window (your 'pop-up' window) to the main window from where it was created. It doesn't matter whether you're working with Windows Control objects or simple data types like string, so I'm going to use a simple example to illustrate how to handle such a situation.
Let's assume you have a Main form that looks like this. It has an OPEN button and a TextBox.
When you click OPEN, it opens up this secondary input window (your pop-up) which looks like this:
Now the idea is this. You click OPEN and opens the Input form, and lets the user enter some text into the TextBox there. Once you click the OK button, it should close the Input window, and display the text entered by the user in the Main window. Remember that at this point the Input window is closed, which is equivalent to your situation.
So I'd make use of Delegates to accomplish this goal. A delegate lets you transfer data between windows which is what you want.
In my Main I'd declare a public delegate with a signature like this:
public delegate void DataTransfer(string data);
That is, this delegate represents a method that takes in a single string parameter, and has void return type. The idea is to let the secondary Input window 'call' a method in the Main, and that method takes in a string parameter. So, if there was a way for us to call a method that resides in the Main from Input, and pass a string, we can then take the user input text in the Input window, and pass it to the Main window. With me so far?
Now, if I write a method like this in the Main, and let it be called from Input, that should accomplish our goal. Here, txtDisplay is the TextBox in the Main form.
public void ReceiveInput(string data)
{
txtDisplay.Text = data;
}
To accomplish this, I would define a delegate of type DataTransfer in the Main form like below, and register the ReceiveInput() method to it. Your Main form code behind should look like this:
public delegate void DataTransfer(string data);
public partial class MainForm : Form
{
public DataTransfer transferDelegate;
InputForm inputForm = null;
public MainForm()
{
InitializeComponent();
transferDelegate += new DataTransfer(ReceiveInput);
}
public void ReceiveInput(string data)
{
txtDisplay.Text = data;
}
private void BtnOpen_Click(object sender, EventArgs e)
{
inputForm = new InputForm(transferDelegate);
inputForm.Show();
}
}
BtnOpen is the OPEN button in the Main form, and when it's clicked, it passes the delegate to the Input form, then opens it. So, accordingly, we need to now modify our Input form:
public partial class InputForm : Form
{
DataTransfer transferDel;
public InputForm(DataTransfer del)
{
InitializeComponent();
transferDel = del;
}
private void BtnOK_Click(object sender, EventArgs e)
{
string data = txtInput.Text;
transferDel.Invoke(data);
Close();
}
}
Here, we modify the constructor so that it takes in a delegate of type DataTransfer, and sets it to the local instance of the same type. Then, at the click of BtnOK on the Input form, we take in the text input by user, and pass that text to the said delegate and invoke it. 'Invoking' is the same as calling the method in the Main form. At this point, you can Clsoe() the Input window as shown above, and you'd still have access to the user input string data from your Main form.
You can use this same approach, and instead of strings you can pass around Controls. However, it's not the best approach to pass around a bunch of controls back and forth, so ideally you would extract the data you need from those controls in your pop-up, and pass only the said data instead of the whole controls.
EDIT: After OP posted the erroneous code.
OK, so here's your issue. The testUserControl class is not a regular class but a control element derived from UserControl. In otherwise, a GUI element. You shouldn't use GUI elements to pass data around. Because, when you do your controlArr[i].getText();, it tries to get the text from the textItem, but textItem is a TextBox Control which doesn't exist at this point because you closed your window. Remember, you do the delegate.Invoke() only once, and at that point *you must send ALL the data back to your main window*.
What you should do is, simply define a class to hold ALL the data you want to pass to your main. For example something like this:
public class DataToPass
{
public string TextBoxText { get; set; }
public string SomeOtherData { get; set; }
// Other stuff you want...
}
Now, instead of passing an array of testUserControl, pass an array of DataToPass. That way, at the Main form you don't have to do the following:
controlArr[i].getText();
Instead you'd simply do something like:
controlArr[i].TextBoxText;
where controlArr now is an array of type DataToPass.
Simply, passing a control derived from UserControl is not a good idea. Just create one class that is capable of holding ALL the data you want to pass and pass it back to the main once.

C# Take combobox item from one form and add its name as text to another

Ok so I'm attempting to create a simple game. In a nutshell it's a resource management game where the player will attempt to manage a thieves guild. In regards to running missions I've created a Thief class, a new instance of which is created when a new thief is recruited. I have coded within the thief class the ability to gain experience and level up.
Here's my specific problem:
I want the player to be able to select which thief/thieves to send on a mission. I have thought about it and figured that opening a new form and populating it with checkboxes is the easiest way to allow this. These checkboxes will be related to a List<thief> of thieves, the player then checks the thieves s/he wants to send and these are then stored in another List<thief> and passed on to the run mission function.
I've built a separate project with the intention of testing and playing around with this before putting it into the main program. The test project consists of two forms: The first (frmMain) with a textbox to hold the selected options and a button to open the second form (frmSelect). Currently I can open and populate the second form (frmSelect) but when I try to add the checked options to the textbox I simply...well can't.
So far I have tried directly accessing the textbox by typing frmMain.txtOptionsDisplay in the cs file of frmSelect but it causes the following error:
An object reference is required for the non-static field, method or
property
I tried to create a new form in frmSelect and make it equal to the active instance of frmMain with: Form frmTemp = frmMain.ActiveForm; and then alter the textbox using frmTemp as a go-between but that produced the error:
'System.Windows.Forms.Form' does not contain a definition for
'txtOptionsDisplay'.
Having searched both google and stackoverflow forums I've encountered answers that I either have never heard of (Threading) or answers that I kind've recognise but can't interpret the code pasted to make it relevant to my problem (delegates).
Any advice or pointers would be fantastic.
EDIT:
frmMain code:
public frmMain()
{
InitializeComponent();
selections.Add("Option 1");
selections.Add("Option 2");
}
private void btnClick_Click(object sender, EventArgs e)
{
frmSelectOptions.Show();
int length = selections.Count();
for (int i = 0; i < length; i++)
{
CheckBox box = new CheckBox();
box.Text = selections[i];
box.AutoSize = true;
box.Location = new Point(50, 50*(i+1));
frmSelectOptions.grpControls.Controls.Add(box);
}
}
public void updateText(string option)
{
txtOptionsDisplay.Text += option;
}
}
frmSelect code:
public List<CheckBox> selectedOptions = new List<CheckBox>();
Form frmTemp = frmMain.ActiveForm;
public frmSelect()
{
InitializeComponent();
}
private void btnSelect_Click(object sender, EventArgs e)
{
foreach (CheckBox box in grpControls.Controls)
{
if (box.Checked == true)
selectedOptions.Add(box);
}
this.Hide();
}
}
I hope this formats correctly... I'm kinda new and don't know how to indent. Oh look there's a preview...
Does this help?
Your problem is that controls defined within a form by default receive the private access identifier. Hence you could just add a property along the lines of
public ControlType ProxyProperty {
get {
return txtOptionsDisplay;
}
}
Besides from that you should think about wether what you're trying is actually a good solution. Manipulating forms from one to another will become a huge clusterfuck in terms of maintenance later on.
I'd suggest using the Singleton pattern for your frmMain. This will help safeguard you from accidentally launching another instance of frmMain and at the same time, will give you access to frmMain's objects. From there, you can either write accessors to Get your txtOptionsDisplay or you can make it public. Below is an example:
public class frmMain
{
private static frmMain Instance = null;
private static object LockObj = new object();
public static frmMain GetMain()
{
// Thread-safe singleton
lock(LockObj)
{
if(Instance == null)
Instance = new frmMain();
return Instance;
}
}
public string GetOptionsDisplayText()
{
return txtOptionsDisplay.Text;
}
}
public class frmSelect
{
private void frmSelect_Load(object sender, EventArgs e)
{
// Set whatever text you want to frmMain's txtOptionsDisplay text
txtDisplay.Text = frmMain.GetMain().GetOptionsDisplayText();
}
}
If you do go this route, don't forget to update Program.cs to use frmMain's singleton.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new frmMain()); - Old method
Application.Run(frmMain.GetMain());
}

Basic use of user controls, closing a user control and opening another, user control parameters

ladies and gentlemen, once again I unfortunately am going to bother you with newbie stuff. I have searched for this information for hours, so if there’s a thread with what I want on it, it’s buried deeper than I could find.
This was my first question here, and Mark Hall was kind enough to set me straight. Since then, I have created a new project and recreated my first three screens as user controls – a container/login, a choice screen, and a main screen (currently empty). If a user has more than one collection, the choice screen pops up and allows them to choose a collection.
I did run into a snag with parameters, but I’m solving that by overloading the form declaration (solution found here) – yes, I know it’s much better to send parameters through calls, but I’d hate to have to create a call for each parameter (do I?) and… OK, OK, I’m better at this than {get, set}. Man, I hate being a newbie.
Anyways, I’m having trouble with the choice form – I can’t seem to call it, close it, then go to the main form. I have no problem (if there’s only one collection) in going straight to the main form, it’s that darn choice form. Yes, I know I could include a choice datagridview, but a few of our end users aren’t the sharpest bulb in the tool shed, and need hand-holding. Anyways, here’s the code.
CONTAINER/LOGIN SCREEN
namespace DeleteThis
{
public partial class ContainerForm : Form
{
Main Main = new Main();
LoginCollectionChoice LoginChoice = new LoginCollectionChoice();
DataTable dtPermissions = new DataTable();
public ContainerForm()
{
InitializeComponent();
Main.ExitEvent += new Main.ExitEventHandler(Main_ExitEvent);
LoginChoice.ExitEvent += new
LoginCollectionChoice.ExitEventHandler(LoginChoice_ExitEvent);
}
void LoginChoice_ExitEvent(object sender, EventArgs e)
{
pnlcontainer.Controls.Remove(LoginChoice);
}
void Main_ExitEvent(object sender, EventArgs e)
{
pnlcontainer.Controls.Remove(Main);
}
private void btnLogin_Click(object sender, EventArgs e)
{
LoginProcedure();
}
private void LoginProcedure()
{
DataTable dtPermissions = AdminClass.GetCollectionsForUser(int.Parse(txtbxUserName.Text));
if (dtPermissions.Rows.Count == 1)
{
//Valid user, one collection. Head right in.
pnlcontainer.Controls.Add(Main);
Main.BringToFront();
}
else
{
//More than one collection found. Giving user choice
LoginCollectionChoice LoginChoice = new LoginCollectionChoice(dtPermissions);
pnlcontainer.Controls.Add(LoginChoice);
LoginChoice.BringToFront();
}
}
private void btnExitProgram_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
I hope I didn't kill anything in the snipping. And now the choice screen…
public partial class LoginCollectionChoice : UserControl
{
public delegate void ExitEventHandler(object sender, EventArgs e);
public event ExitEventHandler ExitEvent;
private static DataTable dtPermit;
DataTable dtPermissions = new DataTable();
public LoginCollectionChoice()
{
}
public LoginCollectionChoice(DataTable dtPermissions)
{
InitializeComponent();
GrdCollection.DataSource = dtPermissions;
dtPermit = dtPermissions;
}
private void btnChoose_Click(object sender, EventArgs e)
{
//Code for the user to choose a collection
ExitEvent(this, new EventArgs());
}
}
I’ve snipped all non-relevent code, I hope you gentlemen and ladies can help this newbie get on the right path. Please, be gentle, you wouldn’t want to see me cry, would you? :) Oh! And if you know of any great tutorial sites, please email them to me. I'd prefer to spend a week on tutorials than a week on stumbling and asking here. Thank you all very much.
Are you calling logonForm.Show()?
It seems like you'd need to show it that way.
You use BringToFront(), but I think it needs to be shown first.
The first thing that jumps out to me is that you are calling
LoginCollectionChoice LoginChoice = new LoginCollectionChoice(dtPermissions);
which is creating a local variable called LoginChoice, which is not the same as your class variable even though they share the same name.
What you want to do is to not declare a local variable in that method. Change that line to
LoginChoice = new LoginCollectionChoice(dtPermissions);
Having said that, I believe tylerjgarland in that you need to call .Show() first. And the way you are closing the form is certainly odd. I would create a form, showDialog, get the result and then close the form that way.

Sending Array List Between Forms [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Currently I am sending one Array List from form2 to form 1 and it works fine.
Form1 form2 = new Form1(this, SampleArrayList); //pass form reference and an arraylist
form2.Show();
this.Hide();
And on form1 I associate SampleArrayList with local Array List.
Form2 formParent;
ArrayList SampleArrayList;
public MainForm(Form2 par, ArrayList _SampleArrayList)
{
InitializeComponent();
this.formParent = par;
this.SampleArrayList = _SampleArrayList;
}
However I want to avoid creating new instance of Form1
form2 = new Form1(this, SampleArrayList);
I want to send Array List to currently running instance of Form1. What would be best way to do this. Thank you
Quote of OP in the comments above:
Form1 is created first, clicking add button creates Form2. Clicking
submit button hides Form2 and creates new instance of Form1 along with
old instance which I didn't want to dispose of. I want to click submit
button and go back to running instance of Form1.
That's really a larger problem then. Here's a nice solution that I like.
public partial class Form1 : Form
{
private string dataFromThisForm; //can be whatever
private void button1_Click(object sender, EventArgs e)
{
Form2 otherForm = new Form2();
//pass some data to other form
otherForm.SomeData = dataFromThisForm;
this.Hide();
otherForm.Show();
//when the other form is closed
otherForm.FormClosed += (sender2, e2) =>
{
this.Show();
string newData = otherForm.NewData;
};
//when the other form is hidden.
otherForm.VisibleChanged += (sender2, e2) =>
{
this.Show();
string newData = otherForm.NewData;
};
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
//Use SomeData to populate controls.
}
public string SomeData { get; set; } //data passed in from other form
public string NewData { get; private set; } //data to expose to other form
private void button1_Click(object sender, EventArgs e)
{
NewData = "SomeDataToPassToForm1";
//this.Close();
this.Hide();
}
}
A few notes:
You're passing around an ArrayList, rather than strings as I did in
this example. An ArrayList is a mutable reference type, whereas
string is immutable. This means that you can just modify the
ArrayList passed to Form2, and those changes will be reflected in
the variable in Form1 since they both point to the same underlying
ArrayList. I left this code in here as it covers the general case
though.
You say that you hide Form2 when you click the submit button.
Normally in this design you would close it since it won't be needed
anymore. If you really don't plan to use it again I suggest closing
it. If you really do plan to show that form again then just hiding
it is fine.
If you close Form2 on submit it will fire the FormClosing event, if
you just hide it it will fire the Visible event. You should probably
remove one of those two event handlers in my code depending on
whether you actually close it or hide it. If you sometimes do one and
sometimes the other then feel free to leave both. You won't actually
harm anything (other than confusing people) if you leave both in even
if you only use one.
A static class that would act as a communications platform within your application could solve the problem or both forms could be owned by the same object.
I would add a method to Form1 that accepts the Array list.
Something like:
public void Setup(ArrayList SampleArrayList)
{
// Do what you need here...
}
Then you could call this method from inside your constructor (to keep the constructor the same), and call Setup when you need to change the list the Form is using.
Your code above would be like this:
// If you needed a new instance of Form1, it wouldn't change
Form1 form2 = new Form1(this, SampleArrayList); //pass form reference and an arraylist
form2.Show();
this.Hide();
// If you already had an instance in the form2 variable
form2.Setup(SampleArrayList);
No matter what, if you are using .NET 2.0 or greater, I would recommend using a generic List to store list data instead of ArrayList.
You can write a static property in the Form1 class if you don't need to create a instance of it. For example:
private static ArrayList _SampleArrayList;
public static ArrayList SampleArrayList
{
get { return _SampleArrayList; }
set { _SampleArrayList = value; }
}
and when you want update the ArrayList write simply:
Form1.SampleArrayList = SampleArrayList;
PS: I reccomend you use a List<> instead of an ArrayList.
If you don't know the type instead of ArrayList use List<object> else List<T>.
EDIT:
If form1 and form2 are both an istance of the same class you only have to make the ArrayList static.

c# Windows form application forms problem

I have a c# windows form app which contains several forms.
Generally, for example, in form1, I create a instance of form2 and then
form1.hide();
form2.show();
But sometimes I want the previous form to show and dispose current form. How can I call the previous form?
Thanks in advance.
To answer your question, you need to maintain references in your views to each other. While this might work it's messy and error prone. It sounds like all your control logic is probably contained within your form class code and I would suggest moving away from that and separate your concerns.
Solving your form management issues becomes very simple if you create a controller class that, at a minimum, manages the creation and disposal of your forms in whatever way you see fit.
So your code sample would actually be launched from a controller class as something like:
public class FormsController
{
private Form form1 = new Form();
private Form form2 = new Form();
public void SwitchForms()
{
form1.hide();
form2.show();
}
}
For further edification checkout the MVC architectural pattern for cleanly working with data, biz logic and UI.
You might consider extending Form to include some properties/fields that allow you to access other forms. the Form class can be inherited from just like most other .Net classes.
You may also consider doing some of that management in the Program.cs file that is part of you project, if neither form is really supposed to be a child of the other.
If you inherit a new class for your form1 from Form and add a method like closeSecondForm you can have it close and dispose the second form.
There are probably a bunch of different ways to solve the issue. These are just a few.
If you set the new form's Owner to a reference to the current form, you can reference that Owner from the new form. You could also subscribe to the new form's Closed() event from the old form, with code to dispose it (though the form can dispose itself by overriding OnClosed, if it doesn't happen there anyway).
This logic should be handled in Program.cs. The Main() method initializes Form1. You want to take control there instead of passing control to the form.
Example:
static class Program
{
internal static Form1 MyForm1;
internal static Form2 MyForm2;
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
// Initialize Form1
MyForm1 = new Form1();
MyForm1.FormClosing += new FormClosingEventHandler(MyForm1_FormClosing);
// You may want to initialize Form2 on-demand instead of up front like here.
MyForm2 = new Form1();
MyForm2.FormClosing += new FormClosingEventHandler(MyForm2_FormClosing);
// Show Form1 first
MyForm1.Show();
// Now we need to occupy the thread so it won't exit the app. This is normally the job of Application.Run.
// An alternative to this is to have a third form you pass on control to.
while (true)
{
Application.DoEvents();
System.Threading.Thread.Sleep(10);
}
}
static void MyForm1_FormClosing(object sender, FormClosingEventArgs e)
{
// Do something, for example show Form2
MyForm2.Show();
// EXAMPLE: We only want to hide it?
e.Cancel = true;
MyForm1.Visible = false;
}
static void MyForm2_FormClosing(object sender, FormClosingEventArgs e)
{
// Do something, for example show Form1
MyForm1.Show();
// EXAMPLE: We only want to hide it?
e.Cancel = true;
MyForm2.Visible = false;
}
}
Since Program is static you can access MyForm1 and MyForm2 anywhere in that project by:
Program.MyForm1.Show();
Program.MyForm2.Hide();
If you plan to have many forms/complex logic I suggest moving this to a separate class. Also consider using a single form and rotate user controls inside it instead.
Form2 myform = new Form2();
myform.show();
this.hide();
You could do this in form1:
...
var form2 = new form2();
form2.Closing += (form2_Closing);
this.hide();
form2.show();
...
private void form2_Closing(object sender, System.EventArgs e)
{
this.show();
}

Categories