My application launches a non-modal dialog on a button click. If user clicks on that button again, I would like to do a check if that form is already running and wonder if its possible?
You can use Application.OpenForms Property
if (Application.OpenForms.OfType<YourNonModalFormType>().Any())
// one is already opened
If you want to close this form:
var form = Application.OpenForms.OfType<YourNonModalFormType>().FirstOrDefault();
if (form != null)
{
// launched
form.Close();
}
Another approach is to manually declare a variable to track your form instance:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Form2 f2 = null;
private void button1_Click(object sender, EventArgs e)
{
if (f2 == null || f2.IsDisposed)
{
f2 = new Form2();
f2.Show();
}
else
{
f2.Close();
}
}
}
Related
This is sample code
Form 1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
}
private void btnAdmin_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show();
}
}
Form 1 open form 2 which ask admin password.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if(textBox1.Text == "123")
{
Setting frm = new Setting();
frm.Show();
this.Close();
}
else
{
MessageBox.Show("You have entered wrong password.");
}
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
now, if you entered right password, it will take to form 3 which is a setting menu for form 1.
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void btnSave_Click(object sender, EventArgs e)
{
Form1 frm = new Form1();
frm.Show();
if (fullscreenYes.Checked == true)
{
frm.FormBorderStyle = FormBorderStyle.None;
}
if (fullscreenYes.Checked == false)
{
frm.FormBorderStyle = FormBorderStyle.FixedSingle;
}
this.Close();
}
}
so now, i want to use radio button change FormBorderStyle of form 1 from form 3 but it doesn't work because my current code just opens a new Form1 and apply that setting to newly opened form 1 and leaving previously opened Form 1 opened.
I end up having 2 form 1 opened like this. How do I change form 1 property directly from form 3 without having 2 form 1 opened? I've been at this for hours but can't figure it out. Help.
There are several ways to achieve your goal.
#1 Give access to Form3 from accessing Form1 through its constructor
private Form1 _owner;
public Form3(Form1 owner)
{
owner = _owner;
}
void DoSomethingToForm1()
{
// do something.. _owner.Prop = ?;
}
Then call Form3 from Form1
new Form3(this).Show();
#2 Use singleton pattern
private static object _lockObj = new object();
private static Form1 _instance = new Form1();
public static Form1 Instance
{
lock(_lockObj)
{
get
{
if(_instance == null || _instance.IsDisposed) _instance = new Form1();
return _instance;
}
}
}
Then call Form1 from Form3
var f = Form1.Instance;
// do something to form1
for manipulating an existing instance of a form so you can modify or set stuff, use OpenForms.OfType
quick sample:
var frm1 = Application.OpenForms.OfType<Form1>().Single();
//set some stuff
frm1.FormBorderStyle = FormBorderStyle.None;
frm1.Show();
There is two Forms in my project : Form1 and Form2.
There is a button in Form1, and what I want to do is closing Form1 and showing Form2 when that button clicked.
First, I tried
Form2 frm = new Form2();
frm.Show();
this.Close();
but as Form1 was closed, Form2 also got closed.
Next, I tried
Form2 frm = new Form2();
frm.Show();
this.Hide();
but there is a disadvantage that the application does not exit when the Form2 is closed.So, I had to put in additional sources in form_FormClosing section of Form2.
Hmm.... I wonder whether this is the right way....So, what is the proper way of handling this problem?
The auto-generated code in Program.cs was written to terminate the application when the startup window is closed. You'll need to tweak it so it only terminates when there are no more windows left. Like this:
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var main = new Form1();
main.FormClosed += new FormClosedEventHandler(FormClosed);
main.Show();
Application.Run();
}
static void FormClosed(object sender, FormClosedEventArgs e) {
((Form)sender).FormClosed -= FormClosed;
if (Application.OpenForms.Count == 0) Application.ExitThread();
else Application.OpenForms[0].FormClosed += FormClosed;
}
By default, the first form controls the lifetime of a Windows Forms application. If you want several independent windows forms your application context should be a separate context from the forms.
public class MyContext : ApplicationContext
{
private List<Form> forms;
private static MyContext context = new MyContext();
private MyContext()
{
forms = new List<Form>();
ShowForm1();
}
public static void ShowForm1()
{
Form form1 = new Form1();
context.AddForm(form1);
form1.Show();
}
private void AddForm(Form f)
{
f.Closed += FormClosed;
forms.Add(f);
}
private void FormClosed(object sender, EventArgs e)
{
Form f = sender as Form;
if (form != null)
forms.Remove(f);
if (forms.Count == 0)
Application.Exit();
}
}
To use the context, pass it to Application.Run (instead of the form). If you want to create another Form1, call MyContext.ShowForm1() etc.
public class Program
{
public void Main()
{
Application.Run(new MyContext());
}
}
You can take this way:
form2 f2=new form2()
this.Hide();
f2.Show();
Hope it was helpful.
Write that into your method which is executed while FormClosing event occure.
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// Display a MsgBox asking the user if he is sure to close
if(MessageBox.Show("Are you sure you want to close?", "My Application", MessageBoxButtons.YesNo)
== DialogResult.Yes)
{
// Cancel the Closing event from closing the form.
e.Cancel = false;
// e.Cancel = true would close the window
}
}
I've got two forms, with subForm being called/created by a buttonClick in Form1. Right now I can initiate subForm, hide Form1, and then unhide Form1 when subForm is closed. What I'd like to be able to do is:
If user clicks changeform button, check to see if subForm is active but hidden
If no, then initiate subForm, else hide Form1, unhide subForm and pass control to it
If user clicks subForm's changeform button, hide subForm, unhide Form1 and pass control to it
If user clicks the "X" in the upper right corner of the form, then close the application, regardless of which form is active. (Right now, selecting the "X" closes the subForm and opens/unhides Form1.)
I can find solutions that do part of the requirements (and maybe all, I'm just too noob to know). To repeat from my previous question here, the code I have so far is:
Form1
private void countClick(object sender, EventArgs e)
{
this.Hide();
subForm myNewForm = new subForm();
myNewForm.ShowDialog();
this.Show();
countSelect.Checked = false;
}
and subForm
private void totalClick(object sender, EventArgs e)
{
this.Close();
}
This works, but it's not really elegant.
I think the best way to do this is to roll your own ApplicationContext. This allows you full control over the application lifetime without having it being tied to a specific Window. See http://msdn.microsoft.com/en-us/library/ms157901.aspx for more information.
Here's an example:
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyApplicationContext());
}
}
public class MyApplicationContext : ApplicationContext
{
public MyApplicationContext()
{
ShowForm1();
}
public void ShowForm1()
{
if (_form2 != null)
_form2.Hide();
if (_form1 == null)
{
_form1 = new Form1(this);
_form1.FormClosed += OnFormClosed;
}
_form1.Show();
MainForm = _form1;
}
public void ShowForm2()
{
if (_form1 != null)
_form1.Hide();
if (_form2 == null)
{
_form2 = new Form2(this);
_form2.FormClosed += OnFormClosed;
}
_form2.Show();
MainForm = _form2;
}
private void OnFormClosed(object sender, FormClosedEventArgs e)
{
if (_form1 != null)
{
_form1.Dispose();
_form1 = null;
}
if (_form2 != null)
{
_form2.Dispose();
_form2 = null;
}
ExitThread();
}
private Form1 _form1;
private Form2 _form2;
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Form1(MyApplicationContext context)
: this()
{
_context = context;
}
private void button1_Click(object sender, EventArgs e)
{
if (_context != null)
_context.ShowForm2();
}
private readonly MyApplicationContext _context;
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public Form2(MyApplicationContext context)
: this()
{
_context = context;
}
private void button1_Click(object sender, EventArgs e)
{
if (_context != null)
_context.ShowForm1();
}
private readonly MyApplicationContext _context;
}
So we'll start out by going to the child form and creating a new event that can be used to notify the parent when it wants to change forms:
public event Action ChangeForm;
Then we fire the event and hide the child form when it wants to change forms:
private void ChangeForm_Click(object sender, EventArgs e)
{
Hide();
if (ChangeForm != null)
ChangeForm();
}
The parent form needs an instance of the child form as an instance field:
private subForm child = new subForm();
And it needs to initialize it in it's constructor, both adding handlers to the ChangeForm event to show the parent, and to the closed event to close itself:
public Form1()
{
InitializeComponent();
child.ChangeForm += () => Show();
child.FormClosed += (s, args) => Close();
}
Then all that's left is for the parent form to hide itself and show the child when it wants to change forms:
private void ChangeForm_Click(object sender, EventArgs e)
{
Hide();
child.Show();
}
Why not simply setting them to foreground, topmost, and so on ?
And setting them back vice versa ?
---added as comment as proposed
To access MainForm fromsubForm:
Create a constructor in your subForm and a field:
MainForm MainFormRef_Field;
subForm(MainForm MainFormRef)
{
this.MainFormRef_Field = MainFormRef;
}
Now you can access your MainForm using this reference. Like this:
MainFormRef_Field.Show();
MainFormRef_Field.Hide(); //or how ever you want to handle it
To access subForm fromMainForm:
To handle your subForm use the object you created for it. Here:
subForm myNewForm = new subForm();
To close whole application if any of the form closes:
Set a Form_Closing event for both forms:
private void MainForm_Closing(object sender, EventArgs e)
{
Application.Exit();
}
private void subForm_Closing(object sender, EventArgs e)
{
Application.Exit();
}
Note:
I am not writing the whole code for all of your cases. Set the variables, check the conditions. Its all up to you that how code it. All the main points you needed I've provided you the solution of them.
I'm trying to have the owner-form minimize when the modal-form is minimized. But when I minimize the modal-form – it disappears completely. (- I can click on the owner-form.)
How do I solve this?
I have:
public partial class Form1 : Form
{
Form2 frm2 = new Form2();
public Form1()
{
InitializeComponent();
frm2.Owner = this;
}
private void button1_Click(object sender, EventArgs e)
{
frm2.ShowDialog();
}
}
And:
class Form2 : Form
{
Form1 frm1;
FormWindowState ws = new FormWindowState();
public Form2()
{
SizeChanged += new EventHandler(Form2_SizeChanged);
}
void Form2_SizeChanged(object sender, EventArgs e)
{
frm1 = (Form1)Owner;
if (WindowState == FormWindowState.Minimized)
{
ws = frm1.WindowState;
frm1.WindowState = FormWindowState.Minimized;
}
else frm1.WindowState = ws;
}
}
(While trying this, I also ran into this: Modal form doesn't appear in tray until minimized and owner-form is clicked once. How do I make it appear? )
This is by design. As part of the modality contract, showing a dialog disables all the other windows in the application. When the user minimizes the dialog window, there are no windows left that the user can access. Making the app unusable. Winforms ensures this cannot happen by automatically closing the dialog when it gets minimized.
Clearly you'll want to prevent this from happening at all. Set the MinimizeBox property to false. The MaximizeBox property ought to be set to false as well, making both buttons disappear from the window caption. Leaving room for the HelpButton btw.
I don't recall every needing this much code to get modal Windows to work. I'm concerned by your comment 'I can click on the owner form', which leads me to believe that the form is nt being correctly set up as modal. By defintion, modal forms must be dealt with before user control can return to the owner form. Minimizinfg the modal form does not constitute properly 'dealing' with the modal form.
Here is some code that I have used in the past. Notes: passing the owner as parameter in ShowDialog establishes the ownership relationship. While I suspect your code works, I've not used it that way.
Also, when I have done this, I have not put any special code in the modal form, and have also disabled all the button in the upper right corner of the form; thereby insuring that the user cannot close, minimize, or maximize the modal form outside of any buttons I have provided.
public partial class Form1 : Form
{
Form2 frm2 = new Form2();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
frm2.ShowDialog(this);
}
}
I hope this helps.
Forms have a property ShowInTaskbar. If it is set to false then the form will never appear on the task bar, even when minimized.
Add a:
Show();
At the end of Form2's event-handler.
I also had the requirement where when minimizing a dialog form it should minimize the application and when restoring the application it should show the dialog again. Here's what I did:
MainForm.cs
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2.Show(this, "Testing 123");
}
}
Form2.cs
public partial class Form2 : Form
{
bool isMinimized;
private Form2()
{
InitializeComponent();
ShowInTaskbar = false;
}
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
if (Owner != null)
{
Owner.Enabled = true;
}
}
private void Form2_Load(object sender, EventArgs e)
{
MinimizeBox = Owner != null;
if (Owner != null)
{
Owner.Enabled = false;
}
}
private void Form2_SizeChanged(object sender, EventArgs e)
{
if (Owner != null)
{
if (WindowState == FormWindowState.Minimized && Owner.WindowState != FormWindowState.Minimized)
{
Owner.Enabled = true;
Owner.WindowState = FormWindowState.Minimized;
isMinimized = true;
}
else if (isMinimized && Owner.WindowState != FormWindowState.Minimized)
{
Owner.Enabled = false;
}
}
}
public static void Show(Form owner, string message)
{
var form2 = new Form2();
form2.label1.Text = message;
if (owner != null)
form2.Show(owner);
else
form2.ShowDialog();
}
}
When I run my application 2 different forms are loaded simultaneously,but one of them is shown.Now I want If one of these form is closed ,other form which is hidden should get closed also.Any Suggestion.
No Parent -Child relation between these forms.
Assuming that the two forms are both in the same process, you can have the second hidden form handle the FormClosed event of the visible form and close it self when the Visible Form's FormClosed event fires.
public partial class Form1 : Form
{
private void Form1_Load(object sender, EventArgs e)
{
// The following does not need to happen in the Load of this form
// Create hidden Form
Form2 frm = new Form2();
// Attach hidden form to this form
frm.AttachTo(this);
}
}
public class Form2 : Form
{
public void AttachTo(Form frmMain)
{
frmMain.FormClosed += new FormClosedEventHandler(frmMain_FormClosed);
}
void frmMain_FormClosed(object sender, FormClosedEventArgs e)
{
this.Close();
}
}
I'm going to assume that this is one application with reference to both forms. Let me know if this is not the case.
Given this assumption, you have the following (shown in pseudocode):
MyApplication
{
Form form1;
Form form2;
}
Each of the form's Close events can close the other form if it is not already closed:
Form1_Close()
{
if(form2 != null)
{
form2.Close();
form2 = null;
}
}
and then:
Form2_Close()
{
if(form1 != null)
{
form1.Close();
form1 = null;
}
}
Does this meet your requirements?