I decided to create a chat application for that I need the single form to be run 2 times (i.e.) I need to view the same Form as two different instances while running it... Is it possible to achieve it.
Note: I dont need it to be done in any of the events. Whenever I run my program 2 instances has to be run.
Two solutions:
Just build your executable and run as many instances of it as you required.
Use more complex solution that utilizes the Application.Run Method (ApplicationContext). See the simplified MSDN example below.
class MyApplicationContext : ApplicationContext
{
private int formCount;
private Form1 form1;
private Form1 form2;
private MyApplicationContext()
{
formCount = 0;
// Create both application forms and handle the Closed event
// to know when both forms are closed.
form1 = new Form1();
form1.Closed += new EventHandler(OnFormClosed);
formCount++;
form2 = new Form1();
form2.Closed += new EventHandler(OnFormClosed);
formCount++;
// Show both forms.
form1.Show();
form2.Show();
}
private void OnFormClosed(object sender, EventArgs e)
{
// When a form is closed, decrement the count of open forms.
// When the count gets to 0, exit the app by calling
// ExitThread().
formCount--;
if (formCount == 0)
ExitThread();
}
[STAThread]
static void Main(string[] args)
{
// Create the MyApplicationContext, that derives from ApplicationContext,
// that manages when the application should exit.
MyApplicationContext context = new MyApplicationContext();
// Run the application with the specific context. It will exit when
// all forms are closed.
Application.Run(context);
}
}
Yes, you can easily create multiple instance of the same form. For example:
new ChatWindowForm.Show();
Also see the Control.Show() method documentation.
Related
I would like to know the appropriate way to completely terminate a Forms application. I open the form in the standard way using the code:
namespace History
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new DisplayHistory());
}
}
}
...and here is a barebones version of the DisplayHistory function with the various things I've tried to terminate the application commented out. The first two cause an unhandled exception stating that I cannot access a disposed object. The third one has no effect at all, and the fourth one won't compile at all because I get an error saying that "Application does not contain a definition for Current":
public DisplayHistory()
{
InitializeComponent();
// this.Close();
// Close();
// Application.Exit();
// Application.Current.Shutdown();
}
Instead of trying to close it in constructor, it's better not to open the form.
But if you really want to close the form in constructor based on some condition, you can subscribe for Load event before InitializeComponent in code and close the form using this.Close()
:
public Form1()
{
if (some criteria)
{
this.Load += (sender, e) => { this.Close(); };
}
return;
InitializeComponent();
}
To close an application normally, you can call below codes anywhere except constructor of form:
this.Close();
Application.Exit();
To force the application to stop, or close it abnormally, you can call Environment.Exit anywhere including the form constructor:
Environment.Exit(1);
While using forms in C# for a project, i have my main Form (mainForm). This form, when clicking the button1, it creates a new thread for the second Form (actionForm). This one, does the same as the main, when i click button1, it creates a new thread for the thid Form (registerForm). This third Form, when i close it, it must recreate the second form.
The problem is that, the threads keep running. The forms, were closed. But when i click the "X" in the third form, it loops, creating new actionsForms.
How can i stop the threads when creating new ones?
Is there a better way to use the Forms?
Code:
namespace Lector
{
public partial class register : Form
{
public register()
{
InitializeComponent();
}
//New thread for Form2
public static void ThreadProc()
{
//New Form
Application.Run(new Form2());
}
//Close Form
private void Registro_FormClosing(Object sender, FormClosingEventArgs e)
{
regresoForma();
}
private void regresoForma()
{
//New thread
System.Threading.Thread nuevoRegistro2 = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));
//Start thread
nuevoRegistro2.Start();
//Close this form
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
I suggest you use this instead and you don't need multi-threading at all:
private void regresoForma()
{
//Hide this form
this.Visible=false;
//Start Form2 but as a dialog
//i.e. this thread will be blocked til Form2 instance closed
(new Form2()).ShowDialog();
//Reshow this form
this.Visible=true;
}
Unless you need to have each form establish itself as an entirely new process, I would recommend using BackgroundWorker to display the new forms if you need them to all be asynchronous. If you're using WinForms. If you are using WPF, You'll need to use Dispatcher to create the new forms.
It really depends on the flow of your forms.
I personally try to avoid creating new threads unless it is absolutely one hundred percent necessary, and I use one of the above mentioned methods to do so unless I'm calling a completely brand new application.
I've been trying to reset my current form to it's original state by closing it, and opening a new one. I want the form objects to be reset,the variables to be re-declared, the class objects to be cleared etc I've got everything working but the class being cleared, no matter what I do it won't create a new one with blank data.
Here is my code:
if (btnRandom.Text == "Reset")
{
SetupScreen form = new SetupScreen();
form.Show();
this.Dispose();
//Create new class for form / or launch load events as normal
form.Mybattleship = new battleship()
form.SetupScreen_Load(this, null);
}
I've tried many methods over the internet and none have worked.. even the overly complicated ones..
Oh I forgot to mention I need the new form to act as if it's just been loaded as normal, so the load events etc trigger
You would be better off making a method that you can call that will set default values for items that you can use when opening form and resetting...
public SetupScreen()
{
InitializeComponent();
SetDefaultValues();
}
private void SetDefaultValues()
{
//start values..
}
public void ResetBtn_Click(object sender, EventArgs e)
{
SetDefaultValues();
}
I have an application that has a main form and a system task tray icon. In the designer of the main form, I dragged the TrayIcon control on the form, so it is a child of the main form.
At this point, when the user presses the close button on the main form, it actually just hides it so that the application wont terminate, unless the user right clicks the TrayIcon and clicks exit. But, the main form has a lot of controls and resources, and when the main form is hidden, it still uses memory for those resources. My goal is to actually dispose of form so it doesn't take up that memory while it is not being used.
Unless I am mistaken, and when the main form is hidden it doesn't take up that memory anymore, but I don't think that is the case.
I'm no expert on memory, I may even be completely mistaken on how memory management works, and thus this question is invalid.
Anyways, if I am correct in that when the main form is only hidden it still takes up memory that can be freed by fully closing the form, is there a way for me to actually close the main form without the application terminating? If so, I would need to create the TrayIcon with code in the Program class instead of in the class of the main form, correct?
No, that's certainly not necessary. It is encouraged by the convenience of the designer but you can easily create an application that only creates a window on demand. You'll have to write code instead. It doesn't take a heckofalot, there's a sample app with basic functionality. Edit the Program.cs file and make it look similar to this (icon required, I called it "SampleIcon"):
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var cms = new ContextMenuStrip();
cms.Items.Add("Show", null, ShowForm);
cms.Items.Add("Exit", null, ExitProgram);
var ni = new NotifyIcon();
ni.Icon = Properties.Resources.SampleIcon;
ni.ContextMenuStrip = cms;
ni.Visible = true;
Application.Run();
ni.Dispose();
}
private static void ShowForm(object sender, EventArgs e) {
// Ensure the window acts like a singleton
if (MainWindow == null) {
MainWindow = new Form1();
MainWindow.FormClosed += delegate { MainWindow = null; };
MainWindow.Show();
}
else {
MainWindow.WindowState = FormWindowState.Normal;
MainWindow.BringToFront();
}
}
private static void ExitProgram(object sender, EventArgs e) {
Application.ExitThread();
}
private static Form MainWindow;
}
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();
}