Reputation: 434
I'm trying to change Forms using threads. Initially I used Hide()
and Show()
to hide the previous Form from the next one, the problem is that when I close the application there is always something running in the backgorund. My idea is this: From Form1 clicking a button goes to Form2 which in turn can choose whether to return to Form1 or go to Form3 which in turn can choose whether to return to Form2 or Form1
This is a piece of code from the Form1 button that if clicked must take me to Form2. The point is that it does not close Form1 and in fact it always remains in the background and when I click the button to close Form2 (using Close ()
) the program does not close and remains at Form1 and if I close that then the program closes definitively
The second form is called OptionGeneral
Thread StartThread = null;
public void btnOptions_Click(object sender, EventArgs e)
{
StartThread = new Thread(SwitchForm);
StartThread.Start();
//Hide();
OptionGeneral option = new OptionGeneral();
option.Show();
}
public void SwitchForm()
{
StartThread.Abort();
}
Upvotes: 0
Views: 276
Reputation: 74605
To me it seems a case of just hiding and showing the forms as per the comments, and closing Form1 if the other forms close.. Forget the showing/hiding via threading bit; there lies a world of pain (use TPL for long running operations/stay away from multithreading if you can):
class Form1{
public Form2 Form2 { get; set; }
Form1(){
//wire forms up to each other
var form3 = new Form3() { Form1 = this };
Form2 = new Form2() { Form1 = this, Form3 = form3 };
form3.Form2 = Form2;
}
void GoToForm2ButtonClick(...){
this.Hide();
Form2.Show();
}
}
class Form2{
public Form1 Form1 { get; set; }
public Form3 Form3 { get; set; }
//event handlers
void GoToForm1ButtonClick(...){
this.Hide();
Form1.Show();
}
void GoToForm3ButtonClick(...){
this.Hide();
Form3.Show();
}
void FormClosing(...){
Form1.Close();
}
}
//event handlers
class Form3{
public Form1 Form1 { get; set; }
public Form2 Form2 { get; set; }
void GoToForm1ButtonClick(...){
this.Hide();
Form1.Show();
}
void GoToForm2ButtonClick(...){
this.Hide();
Form2.Show();
}
void FormClosing(...){
Form1.Close();
}
}
And cue usual commentary about making class names meaningful, rather than just a type name followed by a number
Upvotes: 1
Reputation: 752
Is this a new application or one you are trying to redesign that already runs forms in separate threads...
In general programming in Windows either C++, WinForms or WPF you do the following. Make the interactions you do in the GUI event based. All forms dialogs and GUI elements live in the main thread so data passing is extremely simple and fast.
When real work needs to be done cast the work into a threadpool or task library and when the work is complete marshal the data back to the main ui thred to execute display logic.
In WPF the Dispatcher is your key to pushing data back to the UI. It has been a LONG while since I did webforms.
If your application does not obey these rules you will suffer complicated penatlies. If it is brand new then reboot your development with the strategies I had in mind.
If your application was designed against these rules and you are maintaining it then analyze what kind of work effort it would take to port all the features to a stable architecture and discuss with the people in charge.
Upvotes: 5
Reputation: 593
Do not work with UI elements directly from other thread otherwise you'll get application freeze. Use some dispatching to do it like discussed in this topic How do I update the GUI from another thread?
Another bad thing - don't use thread.Abort() call otherwise your application will be unpredictable and buggy see https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.abort?view=netframework-4.8
The Thread.Abort method should be used with caution. Particularly when you call it to abort a thread other than the current thread, you do not know what code has executed or failed to execute when the ThreadAbortException is thrown. You also cannot be certain of the state of your application or any application and user state that it's responsible for preserving. For example, calling Thread.Abort may prevent the execution of static constructors or the release of unmanaged resources.
Upvotes: 2
Reputation: 500
When you are in the form1() form1 is the main window of the system, which is the boot window, you cannot close it and go to form2(), but you can make the main window form2() and you call form1() before the Initialize Component form2()
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());
}
public Form2()
{
new Form1().ShowDialog();
InitializeComponent();
}
now in form1() you can close window
public Form1()
{
InitializeComponent();
}
private void btn_Close_Click(object sender, EventArgs e)
{
this.Close();
}
Upvotes: 3