I'm trying to show a Form before an application's start and get its DialogResult, so I'm just creating it and using ShowDialog (because Application.Run's return value is void).
What I'm worried about is that it might get 'hijacked' by mistake by some other Form that might be shown at the time. Not by this application, obviously. See What is the meaning of Form.Show(null)? that it's not advisable to use the parameterless overload of ShowDialog.
I have tested and seen that the Form's Owner property was null. But will it always be so? Or should I create a Form and use that as the Owner without showing it? That seems a strange solution but logically it should avoid any problem. Or will that introduce new ones?
Not by this application, obviously
This is already taken care of by Windows, it enforces a strong separation between processes and windows owned by threads. A typical choice for the owner of a dialog for example is the window returned by GetActiveWindow(). The active window is a property of a thread. Which explains for example why a MessageBox.Show() call made from a worker thread is never modal to the rest of the windows.
Making a window modal against the windows of another process is technically possible but requires lots of effort. The app would have to call AttachThreadInput(), a very unsubtle winapi function that nobody ever calls by accident. Also a great source of deadlock.
Unless you are programming in a boat near the Somali coast, there is no good reason to fear your window getting hijacked.
[STAThread]
static void Main()
{
Form1 form1 = new Form1();
//here I suppose the form you want to show
Form1 form2 = new Form2();
form2.ShowDialog(form1);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(form1);
}
Basically you use ShowDialog() when there are no parents for this window. Usually this happens for the main window. If you are opening one window after another, while closing previous, then there will be multiple ShowDialog()s.
If you are showing dialog (which is also a window), then you can specify it's parent to achieve a certain behavior. To example, when alt-tabbing to that window, it's dialog will be shown in front. Think about this as making child-parent relations.
I don't know about the case, when multiple forms are the claiming same parent. But it sounds like a clear mistake, to example:
public Form1 FormMain = new Form1();
...
// show main form
FormMain.ShowDialog();
...
// somewhere in the main form - show dialog
Form2 form2 = new Form2();
form2.ShowDialog(FormMain);
...
// somewhere in form2 - show dialog
Form3 form3 = new Form3();
form3.ShowDialog(FormMain); // wrong, should be form2!
This is not tested because I couldn't recreate a case where the parent is ever anything but null (i.e. a reference to a third-party un-managed parent), but maybe you could do something like this on your form to set the parent to null if it changes:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
this.ParentChanged += MyParentChanged;
}
public void MyParentChanged(Object sender, EventArgs e)
{
this.Parent = null;
}
}
Related
I have two windows forms Form1 and Form2 and a c# class library CLProduct.
Now, Form1 is already open and a method in CLProduct class is called which shows Form2 and at this point I would like to restrict access to Form1 until Form2 is closed.
I have the below code in my method in CLProduct which load
var _frm2= new Form2();
_frm2.ShowDialog();
I know that ShowDialog loads a modal which by default restricts the access to Form1 when ShowDialog is called from Form1 but in my scenario ShowDialog is actually called from a Class which for obvious reasons doesn't restrict Form1 as it is not called from Form1
Form2 is running on a worker thread that's created in Form1 as follows
if (pPBackgroundWorker.IsBusy == false)
{
// Start the asynchronous operation.
pPBackgroundWorker.RunWorkerAsync();
}
Is there a way to handle this from Form1_Load()?
You should simply be able to call ShowDialog for From2 and pass Form1 as an argument and get the desired behavior. (_frm2.ShowDialog(_frm1))
But as HansPassant points out in the comments, if Form2 does not find the appropriate owner itself it most likely means that it is running on a worker thread which can result in some pretty nasty bugs/issues.
I have a form window that has a button, which on click creates an instance of a different form window and launches it. Something like this:
private void button_onclick(stuff)
{
form f = new form2;
form2.showdialog();
}
This form2 has a similar button that launches form3, and so one.
What I would like to do is to create an instance of all my forms in the first from window. I would like to show the first form, have it deactivate but not close, return a value, and then show another one. I am trying to facilitate a "next button" and "back button". In particular, I want to make the back button return to the same instance of the form that called it. I am having a problem because the ShowDialog method I am using suspends the calling form until the called form closes. I want to return to the calling form without closing it, preferable with some kind of return value so I can use some logic to determine what happens next.
Some pseudo code of what I would like to do:
form2;
form3;
form4;
while (form1 not closed)
{
int test;
test = form2.method();
switch test
{
case test == 1
test = form3.method(); break;
case test == 2
test = form4.method(); break;
.
.
.
} //end of while loop
I would appreciate a point in the right direction.
Consider showing/hiding container controls on a single form, rather than different forms. Also, check out some of these examples online for ideas on how to implement back/next:
http://msdn.microsoft.com/en-us/library/7k3w6w59.aspx
http://www.codeproject.com/Articles/4005/A-NET-Wizard-control
Maybe this is a really dumb problem, but I can't close a form.
This is what I'm trying to do:
Start Main form -> Open second form -> Open third form and close the second form..
I use this code to open the second form:
this.Hide();
System.Threading.Thread.Sleep(200);
pauzescreen p = new pauzescreen();
p.Show();
And I use this code to open the third form:
this.WindowState = FormWindowState.Maximized;
Form1 form1 = new Form1();
form1.TopMost = true;
form1.Show();
form1.Activate();
And then I close the second form with this code: (Here is the problem, this doesn't work..)
pauzescreen pauze = new pauzescreen();
pauze.Hide();
Can't explain it very well, but what it does it creates an fullscreen screen capture at the second form (Pauzeform) and at the third form you can select an region.
The second form and third form have no border and are maximized.
You are creating two separate references to two separate forms: p and pauze. To close the original form you would need to retain the reference and call Close() or Hide() on that:
pauzescreen p = new pauzescreen();
p.Show();
// other stuff
p.Hide();
I have a multiform application, and I'm quite fond of using the Program class.
static class Program
{
// declare the forms in the program member space
static Form1 firstForm;
static Form2 secondForm;
static Form3 thirdForm;
}
What I do is in the Main method, initialize the forms.
static void Main()
{
firstForm = new Form1()
// ... so on and so forth
}
Then, whenever you want to show or hide those forms, use
// To hide a form, use its Hide method
Program.firstForm.Hide()
// To show a form, use its Show method
Program.secondForm.Show()
in your code. It's worked in my applications just fine like that. :)
As Sid pointed out, the main problem is that you're creating a new instance of your second form when writing
pauzescreen p = new pauzescreen();
As you're trying to close it in a part of the code different from where your form's instantiation is, one fittable solution, instead of handling events, is to keep reference of your object by passing it as a parameter to the class or method attempting the closure.
Here is an example of how you could work with the same object in two different classes.
I am getting the error message Cannot access a disposed object.
Object name: 'ApplicationProperties'. when I tryo to re-open a form after closing it. I have noticed this is from exiting forms, and exiting is "Disposing" of them, so I have put the following code in all of my accept buttons, and cancel buttons (any button that closes a form).
this.Hide();
this.Parent = null;
This code is just hiding the form. Not closing the form.
So what my problem is, is that when I click the 'x' button on the form, then try to re-open the form I still get the error message. I have tried a couple differnet ways to modify the exiting funciton of the form such as:
private void ApplicationProperties_FormClosing(object sender, FormClosingEventArgs e)
{
//Hiding the window, because closing it makes the window unaccessible.
this.Hide();
this.Parent = null;
}
But this has brought me no luck. I was wondering if anyone knows how to solve this problem. Here is the code that is working for me inside my cancel and accept buttons. It is the same for all of my buttons that close forms.
private void OptionsCancelbtn_Click(object sender, EventArgs e)
{
//Hiding the window, because closing it makes the window unaccessible.
this.Hide();
this.Parent = null;
}
I have declared the instance at the top of my class on form1, and have a button inside form1 that opens form2.
public partial class MainBox : Form
{
//Making a name for the ApplicationProperties form. It can be opened when called.
ApplicationProperties ApplicationPropertiesWindow = new ApplicationProperties();
private void ApplicationPropertiesbtn_Click(object sender, EventArgs e)
{
//Show the properties window.
ApplicationPropertiesWindow.Show();
}//End ApplicationProperties button.
}
After I close the program with the 'x' button on the second form I cannot access form2 again because of the error message firing at ApplicationPropertiesWindow.Show();
Inside form2 I have the following code:
public partial class ApplicationProperties : Form
{
//Creates and sets the instance MainBoxWindow.
public MainBox MainBoxWindow { get; set; }
Try this in your FormClosing event:
private void ApplicationProperties_FormClosing(object sender, FormClosingEventArgs e)
{
//Hiding the window, because closing it makes the window unaccessible.
this.Hide();
this.Parent = null;
e.Cancel = true; //hides the form, cancels closing event
}
cause right now it is still closing the form, thus still causing the error.
After I close the program with the 'x' button on the second form I
cannot access form2 again because of the error message firing at
ApplicationPropertiesWindow.Show();
When a form is closed (Form.Close), the form itself and all of its associated resources are freed. There are only two exceptions to this automatic disposal, as noted in the documentation:
The form is part of a MDI application and not visible.
The form was displayed as a modal dialog using ShowDialog (as opposed to Show). It is designed this way so that you can access properties of the dialog (e.g. to retrieve user input) after the user has closed it.
In both of these special cases, you are responsible for manually calling the Dispose method of the form. The second case is by far the most common (no one really uses the MDI paradigm anymore), and is handled easily with a using statement:
using (MyDialogBox dlg = new MyDialogBox())
{
DialogResult result = dlg.ShowModal(this);
if (result == DialogResult.Yes)
{
// access members of "dlg", and
// do whatever the user asked
}
} // the Dispose method is automatically called here
In your case, as is typical, the call to the Close method is closing and destroying the form. You already know that you cannot access a disposed object (because it no longer exists!), so that's why you're getting the exception when you try to show it. In order to show the form again after it has been closed, you need to create a new instance of the form class:
MyForm frm = new MyForm();
frm.Show();
// ...
frm.Close();
This is really the best method. A new instance of the form will be identical to the one you're closing because it was created from the same class. You would do best to start thinking in object-oriented terms and avoid singleton-based designs whenever possible. Each form that shows up on the screen is a new, independent object. Once that object is closed and destroyed, you cannot use it any longer. If you want to use it again, you need to create a new object and display it.
The Hide method is more of a hack, useful only when you want to temporarily hide the current instance of a form while still retaining its state (e.g., the values of its member properties, its control states, etc.). This works only with singleton objects that will never be destroyed, and must be carefully designed and maintained. It also means that this form object consumes resources all the time, whether it is being used or not, which is wasteful.
If you must do this, you'll need to track down what is causing your form instance to be disposed. Without seeing all of your code, it's hard for me to do anything but guess at where the problem might be. It is likely related to your use of the AcceptButton and/or CancelButton properties. Either way, the best and cleanest solution is to override the OnFormClosing method and prevent your form from ever being closed. You'll hide it instead:
public class MyForm : Form
{
protected virtual void OnFormClosing(FormClosingEventArgs e)
{
// Prevent the form from closing.
e.Cancel = true;
// Hide it instead.
this.Hide();
}
// ...other code in your form class
}
The advantage of this is that you only have to have the code in one place, local to the responsible class, rather than exposed to external code and scattered throughout your application. And of course, it also prevents the form from ever being closed by framework code outside of your control.
I have no idea why you're setting the Parent property to null. A top-level window (which is what all forms are) can never have a parent. Only child windows (e.g. controls) have parents. It can have an owner, but it will not necessarily. It depends on whether you pass an owner window as an argument when calling the Show method.
First remove this.Parent=null bcose this is not required when you hiding the Form
Now when you hiding the Form and if you still want to access this Form store form in static var . Bcous when object is no longer in use garbage collector dispose it and it will no longer available .
The problem, at least perhaps part of it, looks like a bit of class interdependence.
When you initialize an ApplicationProperties instance, you're creating a reference to a MainBox object, but in the definition of the MainBox class, you're creating a new ApplicationsProperties object, which references a MainBox.... I'm even confusing myself. Is MainBox your parent form, the one that loads when you start the application?
I wouldn't be surprised if some stuff in MainBox is getting destroyed inadvertently if you set a reference to it in the ApplicationProperites class... which is disposing when you click "X". Again, this is an educated guess; I'm not sure if that's the reason but even if the code isn't wrong per se, it looks quirky to me.
If you want your ApplicationProperties window to last forever and to simplify things, just initialize a static instance of it at the beginning of whatever form is going to persist the duration of your application, and show/hide it similar to what you were attempting originally. If you want to be efficient and fundamental, construct and dispose ApplicationProperties whenever you need to let the user modify it, but kill the circular dependency.
Does anyone know how can I know if the Windows Form Application (C#) is open or that the client closed it?
(In my App I have a Windows Form Application (Form1) that allow the user to open another Forms (Form2). I want to know if the Form2 is open or close.)
I need to know that because I run the Form2 from a thread, and I want to make the thread runnig until the user close Form2.
Many thanks!
You can check if a form of a given type is open in your application like this (using LINQ):
if (Application.OpenForms.OfType<Form2>().Count() > 0)
{
// there is an instance of Form2 loaded
}
You need to elaborate on your question a bit more. Are you talking about monitoring the application from another application? Or that one form needs to know if another one is open? Or a form needs to know when another form closes?
There are a couple of ways to monitor forms closing within the same application.
Calling ShowDialog() on your form instead of Show() will ensure that code following the ShowDialog() call doesn't get executed until the user closes the form.
The Form class has a Visible property, which returns true/false depending on whether the form is visible or not.
As for the application itself, there is an ApplicationExit event on the static Application class which gets called just before the application closes so you could listen to that event if, for example, you need to perform some clean-up on exit.
If you want to run only single instance of application, check this link.
There you will also see how to check whether a process is still active.
If you mean MDI application with its child forms:
private Dictionary<Type, Form> SingleInstanceForms = new Dictionary<Type, Form>();
public Form ActivateForm<T>() where T : Form, new()
{
Cursor.Current = Cursors.WaitCursor;
if (!this.SingleInstanceForms.ContainsKey(typeof(T)))
{
T newForm = new T();
//setup child
newForm.MdiParent = this;
newForm.WindowState = FormWindowState.Maximized;
//newForm.Icon = Icon;
newForm.FormClosed += new FormClosedEventHandler(delegate(object sender, FormClosedEventArgs e)
{
this.SingleInstanceForms.Remove(sender.GetType());
});
this.SingleInstanceForms.Add(typeof(T), newForm);
newForm.Show();
this.Refresh();
}
Form formToActivate = this.SingleInstanceForms[typeof(T)];
formToActivate.Activate();
Cursor.Current = Cursors.Default;
return formToActivate;
}
this will create the form child if hasn't been created yet and activate it if it has been created.
sample: ActivateForm<dlgChildOne>();