I have wanted to navigate through forms so when I client the buttonKlient I go to the Form2 then when I click control 'x' I go back to Form1 I got:
(the fk is Form2)
private void button1_Click(object sender, EventArgs e) {
if (fk == null)
fk = new OknoKlient();
fk.Tag = this;
fk.Show(this);//here is ObjectDisposedException
Hide();
}
Then in Form2
protected override void OnFormClosing(FormClosingEventArgs e) {
if (e.CloseReason == CloseReason.WindowsShutDown) return;
var form1 = (Form1)Tag;
form1.Show();
Hide();
// DO WHATEVER HERE
}
When I click button1 the Form2 fk opens, then I close it by x control then click the button1 again and I get the exception ObjectDisposedException.
protected override void OnFormClosing(FormClosingEventArgs e) {
if (e.CloseReason == CloseReason.WindowsShutDown) return;
e.Cancel = true; // <---------------------- this
var form1 = (Form1)Tag;
form1.Show();
Hide();
// DO WHATEVER HERE
}
You're hiding the form yes.. but the form is still being disposed. You need to add e.Cancel = true; to cancel the form closing.
Related
I'm building the WPF app with multiple forms, and my goal is that, on, let's say LoginForm I have a button called Login, which, when clicked, closes current form (LoginForm from above) and opens another form (let's say Form1).
Note that I'm trying to have only one form opened at a time.
Code -
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
if(everything okay)
{
Form1 frm = new Form1();
frm.Show();
Close();
}
else
{
return;
}
}
This works fine. But, my second idea is that, if X in the top right corner is clicked, I want to close this form, and not to open any other, basically exiting the app.
Code-
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
MessageBoxResult rez = MessageBox.Show("Do you wish to leave the app?", "Question?", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (rez != MessageBoxResult.Yes)
{
e.Cancel = true;
}
}
This is where my problem starts, I've found that Window_Closing and this.Close() are same event, so, when I click the Login button, MessageBoxResult still shows up, even tho that is not my goal. I want to somehow separate those two events, if that is possible. How can I do so?
You could temporarily unhook the event handler just before you call Close():
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
if (everything okay)
{
Form1 frm = new Form1();
frm.Show();
Closing -= Window_Closing;
Close();
Closing += Window_Closing;
}
else
{
return;
}
}
Or use a bool variable to determine whether to display the MessageBox:
private bool _showMessageBox = true;
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
if (everything okay)
{
Form1 frm = new Form1();
frm.Show();
_showMessageBox = false;
Close();
_showMessageBox = true;
}
else
{
return;
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!_showMessageBox)
return;
MessageBoxResult rez = MessageBox.Show("Do you wish to leave the app?", "Question?", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (rez != MessageBoxResult.Yes)
{
e.Cancel = true;
}
}
this.Close is not a event. this.Close() is a method and after that the event Window_Closing is raised
Try something like that:
Form1 frm = new Form1();
Hide();
frm.ShowDialog();
Close();
you create a form, then you hide the login form and then you show the Dialog of the form. The Close will then be raised after the new Form1() is closed.
I have 2 forms
Form1
Form2
I have one button in Form1
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 =new Form2();
f2.ShowDialog();
f2.Dispose();
}
but issue is while opening form it's bliking and diasparing
i have tried to use show() also but not solved the problem
If i have not used Disposed method then first time when run the form it appering and disappered but sencond time onward by clicking on button it's working fine...
In Form2_Load event i am using this two property
private void Form2_Load(object sender, EventArgs e)
{
this.RightToLeft = RightToLeft.Yes;
this.RightToLeftLayout = true;
}
Don't change the form layout while its loading. Change it before you launch. Remove the code from Form2_Load and put it in button1_Click:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 =new Form2();
f2.RightToLeft = RightToLeft.Yes;
f2.RightToLeftLayout = true;
f2.ShowDialog();
}
I would guess you want to show and close the form2 using the same button. And I doubt your initial problem description
"issue is while opening form it's bliking and diasparing"
I think form2 is not 'blinking' while opening, but is 'blinking' while you try to click the button again in form1
ShowDialog() will exit your execution after u called it. Mean, it will exit the execution after you click the button.
Thus, you should try Show() with conditional statement within the button click event
In form1.cs
bool flag = false;
Form2 frm2;
private void button1_Click(object sender, EventArgs e)
{
if (flag == false)
{
frm2 = new Form2();
frm2.Show();
frm2.Load += new EventHandler(frm2_Load);
frm2.FormClosed += new FormClosedEventHandler(frm2_FormClosed);
flag = true;
}
else
{
frm2.Close();
flag = false;
}
}
void frm2_Load(object sender, EventArgs e)
{
//set what ever properties you like
}
void frm2_FormClosed(object sender, FormClosedEventArgs e)
{
flag = false;
}
See also: A dialog disables all of the windows that your program displays
Remove this Property
this.RightToLeft = RightToLeft.Yes;
and run your form...
Try This :
private void button1_Click(object sender, EventArgs e)
{
using(Form2 f2 =new Form2())
{
f2.ShowDialog();
}
}
On button click, I open a new form (lets say Form2), but I don't want that Form2 to open more than 1time. And I don't want to use .ShowDialog(), because it wont allow me to go to the Previous Form. How can I do that ?
You can use Application.OpenForms property to check if form already opened:
if (!Application.OpenForms.OfType<Form2>().Any())
{
Form2 form2 = new Form2();
form2.Show();
}
You can show existing form instead of creating new:
Form2 _form2 = null;
void Button1_Click(object sender, EventArgs e)
{
if (_form2 == null)
{
_form2 = new Form2();
_form2.Closed += Form2_Closed;
}
_form2.Show();
_form2.BringToFront();
}
private void Form2_Closed(object sender, System.EventArgs e)
{
_form2 = null;
}
You can issue the Show method, which will show the form and allow the users to get back to the form, but then you can also override the OnClosing event of the form:
protected override void OnClosing(CancelEventArgs e)
{
e.Cancel = true;
}
and that will keep the users from being able to literally close the form. Finally, if you wanted, you could Hide the form when the user closes it:
protected override void OnClosing(CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
}
and then you'll need to hold on to that instance in the first form so that you can re-show it when the button is clicked. So in the first form you might have a class field like this:
private Form2 _form2 = new Form2();
and then in the button click it would look like this:
_form2.Show();
and since they can't actually close the form this will always work.
You can try something like
bool windowIsNotOpen;
Mutex mutext = new Mutex(true, "Form2", out windowIsNotOpen);
if (!windowIsNotOpen)
{
// Form2 is already open
return;
}
You can do a static property that tells you whether it's open or not. You'd set it when the form is opened, and turn it off when the form is closed.
class Form2 {
public static bool IsOpen { get;set; }
public Form2() {
Load += (sender, e) => { Form2.IsOpen = true; };
Closed += (sender, e) => { Form2.IsOpen = false; };
}
}
Whenever you want to open it, check the flag first.
Form2 f;
bool isOpen = false;
private void button1_Click(object sender, EventArgs e)
{
if (f == null)
{
f = new Form2(); ;
f.FormClosed += new FormClosedEventHandler(f_FormClosed);
}
if (!isOpen)
{
isOpen = true;
f.Show();
}
}
void f_FormClosed(object sender, FormClosedEventArgs e)
{
isOpen = false;
}
Try this or use Application.OpenForms and check which one opened
I am developing a C# Windows Forms application. I would like to have a single instance of all the forms.
So, when the user clicks on the Contact button, for instance, twice, instead of having two contact forms, I would to bring the single instance contact form to the front.
How can I achieve this?
Check if the form exists in collection of open forms before creating and showing the form using Application.OpenForms
if (System.Windows.Forms.Application.OpenForms["Form1"] as Form1 != null)
MessageBox.Show("Form1 is opened");
else
MessageBox.Show("Form1 is not opened");
public static Form GetOpenedForm<T>() where T: Form {
foreach (Form openForm in Application.OpenForms) {
if (openForm.GetType() == typeof(T)) {
return openForm;
}
}
return null;
}
And in your code, where you create the ContactForm:
ContactForm form = (ContactForm) GetOpenedForm<ContactForm>();
if (form == null) {
form = new ContactForm();
form.Show();
} else {
form.Select();
}
Simple as that:
Form fc = Application.OpenForms["Form1"];
if (fc != null)
{
fc.Focus();
}
else
{
Form1 f1 = new Form1();
f1.Show();
}
You can disable the contactButton when it is clicked and open the contactForm-
private void contactButton_Click(object sender, EventArgs e)
{
contactButton.Enabled=false;
//code to open the contactForm
}
When the contactForm is closed, you can re-enable the button-
contactButton.Enabled=true;
Try this combo
First make contact form a global object
private ContactForm contactForm;
Then your contact button handler:
private void contactButton_Click(object sender, EventArgs e)
{
if (contactForm == null)
{
contactForm = new ContactForm();
contactForm.FormClosing += new FormClosingEventHandler(contactForm_FormClosing);
}
contactForm.Show();
}
Then handle the FormClosing event of the ContactForm to hide it rather than close it:
private void contactForm_FormClosing(object sender, FormClosingEventArgs e)
{
contactForm.Hide();
e.Cancel = true;
}
Or if you want the contact form to close, and open as new next time, handle the FormClosed instead:
private void contactForm_FormClosed(object sender, FormClosedEventArgs e)
{
contactForm = null;
}
Then next time the button is clicked, the null if clause will be caught and the form will be set to a new instance and opened.
Form2 form2 = null;
private void button1_Click(object sender, EventArgs e)
{
bool isFormExists = false;
foreach (Form openForm in Application.OpenForms)
{
if (openForm == form2 && openForm!=null)
{
openForm.Focus();
isFormExists = true;
break;
}
}
if (!isFormExists)
{
form2 = new Form2();
form2.Show();
}
}
I'd go with Otiel's answer. Also you can add a WindowState, because if the form is minimized it won't be shown. this answer can be used to get the restore method.
ContactForm form = (ContactForm) GetOpenedForm<ContactForm>();
if (form == null) {
form = new ContactForm();
form.Show();
} else {
//use this (if you want it to be restored to normal and focused)
//no need of extension method
//form.WindowState = FormWindowState.Normal;
//form.Select();
//or use this if you want it to be restored as previous state and focused
//You need a Restore extension method that can be found in the link above
form.Focus();
form.Restore();
}
I was wondering if there are any event handlers if the user clicked the close button in a windows form. My initial plan was when the user clicked the close button, it will return a boolean to the caller or whoever called that form. for example
public void newWindow(){
NewForm nw = new NewForm();
nw.ShowDialog();
if(nw.isClosed){
do something
}
}
is that possible?
If you are using .ShowDialog(), you can obtain a result via the DialogResult property.
public void newWindow()
{
Form1 nw = new Form1();
DialogResult result = nw.ShowDialog();
//do something after the dialog closed...
}
Then in your click event handlers on Form1:
private void buttonOk_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
private void buttonCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
If you do not want to open the new form as a dialog, you can do this:
public void newWindow()
{
Form2 nw = new Form2();
nw.FormClosed += nw_FormClosed;
nw.Show();
}
void nw_FormClosed(object sender, FormClosedEventArgs e)
{
var form = sender as Form2;
form.FormClosed -= nw_FormClosed; //unhook the event handler
//you can still retrieve the DialogResult if you want it...
DialogResult result = form.DialogResult;
//do something
}
You should take a look at the FormClosing Event or since you are using ShowDialog you can do something like this. You can also change the DialogResult that is returned in the FormClosing Event.
DialogResult dr = nw.ShowDialog();
if (dr == DialogResult.Cancel)
{
//Do Stuff
}
You're almost there!
You don't need the if(nw.isClosed), the line do something will only get executed when nw will be closed
If you need to 'return' a value from that dialog, know this: The dialog is not immediatly released when you close it. So you can do something like this:
NewForm nw = new NewForm();
nw.ShowDialog();
var x = nw.Property1