Cannot access a disposed object? - c#

I have a countdown Timer form - on the first form the user will enter the countdown time - warning times, end message, etc. There are also two Radio buttons (Max/Min) and depending on which is selected they will open a new Max or Min form where the time will actually start to countdown. It is working fine and counting down as I expect. However, if I exit the Max or Min form and try to run again with new times I get the error. The code is below - note the comment out ShowDialog(this); was something I tried - it let me close and open the new forms ok but it did not actually start the countdown. UpdateLabels is the function that does the updating of Labels.
bool Max = rbMax.Checked;
if (Max == true)
{
//_Max.ShowDialog(this);
_Max.Show();
}
else
//_Min.ShowDialog(this);
_Min.Show();
UpdateLabels();
}
I also tried the following which I read online as a possible solution but it also did not work...
private void Max_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
this.Parent = null;
}
Can anyone help me out - I can post the UpdateLabels function if needed. I am pretty new to UI C# development so any help would be great. Thanks.

The problem is, that a closed form can not be used anymore (be reopened). Thats why the code you posted tries to stop closing and only hides your window. But for doing this, the Cancel-property must be set to true:
private void Max_FormClosing(object sender, FormClosingEventArgs e) {
this.Hide();
this.Parent = null;
e.Cancel=true;
}
To show the form after closing it this way, show it with the Show() method.
However this is probably only a workaround and you could solve the problem with another design.
Maybe it would be wise, to create a new instance of your form, every time you need it, instead of trying to reopen it every time. This also has the advantage that the form only requesires resources if it is really needed.

What you can do is add a following check before calling .Show method:
if(_Max == null || _Max.IsDisposed)
_Max = new MaxForm();
_Max.Show();
and similarly for _Min form

Whenever a form is closed, all its resources are freed. This means that you can't access the object any more, since it no longer exists - it's been freed and deleted from memory. To prevent that, you can cancel the closing of the form, and hide it instead (which will appear transparent to the user).
this.Hide();
e.Cancel=true;
An updated version of your code is as follows:
private void Max_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
this.Parent = null;
}

The solution is simple that instantiate the object of the called form in the button click event e.g.
private void buttonSetting_Click( object sender, EventArgs e )
{
***_setting = new SettingWindow();*** //When I need to show the settings window
_setting.Show();
}

create new instatnce if object is not available
if(frmRGB==nullptr || frmRGB.IsDisposed==true )
{
frmRGB= new Form();
}

Create Object inside button click event
like this
private void btn_supplier_order_Click(object sender, EventArgs e)
{
form_supplier_order so = new form_supplier_order();
so.Show();
}

Related

bringing a windows form, form to the front without minimising other windows

Hi I'm relatively new to C# and completely new to windows form and basically trying to create a subliminal messaging program that at timed intervals will quickly display a message for it to then be hidden again.
I've managed to by looking through various other posts created another form that will pop up and then hide very quickly using
msgObject.Activate();
that brings the form to the front. However it is stopping me from being able to type when I'm working and I basically wanting to know if it is possible to make some kind of message or form appear at the front of all my other programs without it interrupting my current work or opening or closing of other windows and tasks if that makes sense. As currently it brings the form to the front of everything but will also stop me from being able to type etc.
I'm not sure if this is possible with my current method of using a form but if there is a way of achieving the result I'm after I'd be very grateful to find out
Thanks.
Here is more of my code to clarify
public partial class FormHomePage : Form
{
private bool startSubliminal = false;
msg msgObject = new msg();
List<string> subliminalMessages = new List<string>();
public FormHomePage()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
if (startSubliminal)
{
msgObject.Show();
msgObject.BringToFront();
msgObject.Activate();
}
}
private void button1_Click(object sender, EventArgs e)
{
subliminalMessages.Add(txtBox1.Text);
msgObject.LabelText = txtBox1.Text;
txtBox1.Text = string.Empty;
startSubliminal = true;
msgObject.Show();
msgObject.BringToFront();
}
private void timer2_Tick(object sender, EventArgs e)
{
msgObject.Hide();
}
}
How are you showing the second form (the message form) in the first place? You're probably using .Show() (right?), which will make the form "steal" the focus anyway. The same applies to .Activate() and .BringToFront().
Instead, what you can do is to show the message form and make sure it stays on top the current form, and then activate the current/main form once again.
Something like this should work:
var frm = new YourMsgForm();
frm.Show(this);
this.Activate();
Here's a demonstration:
Note that I used .Show(this) instead of .Show(), that's in order to set the current form as the Owner of the new one, that way we guarantee that the new form will stay on top of the current one. This is equivalent to calling frm.Owner = this; then frm.Show();.
Another way to make sure the form stays on top is by setting the TopMost property instead of the Owner property. However, doing so will make the new form on top of the other windows as well (not just your application).

How to open recently closed or hide form

I've researched thoroughly but still i cant find the best solution for this..
I have a 3 buttons, BACK - HOME - FORWARD ..
This is just like the buttons on the upper left of browser .. and im trying to do this on a form..
what i have is this ..
the back button code is
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
}
// simply hiding the form .. so that the previous form will be shown..
the home button code is this..
private void button2_Click(object sender, EventArgs e)
{
for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
{
if (Application.OpenForms[i].Name != "HomePage")
Application.OpenForms[i].Close();
}
}
// this will show the HomePage form and close other forms whos name is not "HomePage"
the Problem is when i press the Back Button , im hiding it .. how can a button will re open a previously closed or hided form ?
I hope you can Help me! Thanks!
private void button3_Click(object sender, EventArgs e)
{
???????
}
You would need to store a reference to the form that you wish to open again.
There are a couple of options to do this, but if you simply wanted to allow the user to go "Forward" once, you could just store a reference to the form like so:
internal class MyHistory {
internal static Form LastForm;
}
// ........
private void button1_Click(object sender, EventArgs e)
{
MyHistory.LastForm = this;
this.Hide();
}
// ........
private void button3_Click(object sender, EventArgs e)
{
MyHistory.LastForm.Show();
}
Of course, you could maintain a full stack of history items and traverse back/forwards through them if you wanted to be more comprehensive than this.
Note that, if you .Close() your form, you won't be able to reopen it as the reference will be disposed of once it is closed. This method would only work if you were to .Hide() it, which keeps the form instance valid, just hides the form from the user's view.
you could use a form list which holds all initialized forms. that way you can hide, show, add and remove forms dynamically.
List<Form> lstForms = new List<Form>();
then when you add a form:
Form newForm = new Form();
lstForms.Add(newForm);
Hiding a Form:
lstForms(x).Hide(); //x = index of Form you want to hide
Showing a Form
lstForms(x).Show(); //x = index of Form you want to hide
Removing a Form (when closing it for example)
lstForms.RemoveAt(x);
that way you can dynamically work with forms and it is much easier to keep an overview if you have many forms...

Form_Activated is messing up closing the program

I'm currently trying to bring two forms to the front when I activate them from the Task bar or via Alt+Tab. The problem is that I can't close the main form if the second one exists:
This is the code I use
private void Haupt_Activated(object sender, EventArgs e)
{
cardLibrary.Focus(); //Focus the second form
this.Focus(); //refocus the first one
}
What am I doing from?
EDIT:
Haupt is the main form.
CardLib is variable in Haupt
this is how CardLib is called:
private void cMenuOpenLibrary_Click(object sender, EventArgs e)
{
if (!Config.libOpen)
{
if (cardLibrary == null) cardLibrary = new CardLib(this);
cardLibrary.Show();
cardLibrary.Left = this.Left - cardLibrary.Width - 5;
cardLibrary.Top = this.Top;
}
}
EDIT 2: Sry I was being dumb. Adding closing the CardLib via Haupt_FormClosed fixed it.
If you are calling second form from
Second.ShowDialog();
then this will create this problem as a dialog retains focus until it is closed
Instead of
Second.ShowDialog();
use
Second.Show();
How can this.focus in second form focus the first form???
this.Focus(); //refocus the first one

Winform appears twice

I am working on a personal project in winforms just to gain some experience in it since I've never had the chance to work with it before. So, I'm quite the n00b when it comes to Winforms. This is the error I'm encountering:
In form BudgetTracker, I have a button called 'AddCat'. Below is the form's constructor and the button's click eventHandler:
public form_BudgetTracker()
{
InitializeComponent();
setEvents();
}
public void setEvents()
{
this.btn_AddCat.Click += new System.EventHandler(this.btn_AddCat_Click);
}
private void btn_AddCat_Click(object sender, EventArgs e)
{
form_NewCat NewCatForm = new form_NewCat();
var NewCatFormResult = NewCatForm.ShowDialog();
NewCatForm.Show();
}
In the NewCat form that comes up, I have a Cancel button. Code:
public form_NewCat()
{
InitializeComponent();
SetEvents();
}
private void SetEvents()
{
this.btn_Add.Click += new System.EventHandler(this.btn_Add_Click);
this.btn_Cancel.Click += new System.EventHandler(this.btn_Cancel_Click);
}
private void btn_Cancel_Click(object sender, EventArgs e)
{
this.Close();
}
The problem I'm facing is, when I click Add, the new form comes up. At this point, if I click Cancel, the form disappears but instantly a new instance of the form appears. I then click cancel again, and the form disappears.
What part of my code is making the form appear twice. I checked the contructors etc, but couldn't figure it out. Any help or pointers would be appreciated.
PS - As I mentioned, I'm new to winforms programming, so any cues or pointers would be appreciated as well.
private void btn_AddCat_Click(object sender, EventArgs e)
{
form_NewCat NewCatForm = new form_NewCat();
var NewCatFormResult = NewCatForm.ShowDialog(); // <-- opens the first time
NewCatForm.Show(); // <-- opens the second time
}
Judging from your code, you're simply showing the form twice!!!
form_NewCat NewCatForm = new form_NewCat();
var NewCatFormResult = NewCatForm.ShowDialog();
NewCatForm.Show();
The second line shows the form and blocks the method until DialogResult is set, then the third line shows the form without blocking the method.
Simply remove the third line!
Try stepping through the code using the F8 key instead of running it, or hitting F5. It will show you line by line what it's about to execute.
delete NewCatForm.Show();

Working with Forms

I'im writing a program that works with 2 forms, the main form and the form where the configuration is made, so when the user clicks toolstripmenu->Preferences the Preferences form is showned and I want it to make the user only capable of having one Preferences form at a time.
When I use:
Prefs preferencias = new Prefs;
private void preferenciasToolStripMenuItem_Click(object sender, EventArgs e)
{
preferencias.Show();
}
It works, but when I close the Preferences form and try to open a new one the program crashes.
And When I use:
private void preferenciasToolStripMenuItem_Click(object sender, EventArgs e)
{
Prefs preferencias = new Prefs;
preferencias.Show();
}
The user can hav multiple Preferences form.
What can I do?
Thanks in advance.
It sounds like you want a modal dialog, so you need to use the ShowDialog( ) method instead of Show( ):
private void preferenciasToolStripMenuItem_Click(object sender, EventArgs e)
{
preferencias.ShowDialog();
}
The ShowDialog() that others have suggested is a good answer. If you're interested in an alternative, here's something I sometimes do:
private void FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
Hide();
}
}
What this does is simply hides the form so that if you show it again, its already loaded into memory. Additionally, if you have a timer or some other thread in that form running, it can still run and do its thing.
preferencias.ShowDialog()
will only allow one preference window to be open .
You can use the Application.OpenForms property in your menu item's click event to check if a form of that type is already open. If there is no form of that type open, then you can open your instance. If there is, it simply won't show.
foreach (Form form in Application.OpenForms) {
if (form.GetType() != typeof(PreferencesForm)) {
new PreferencesForm().Show();
}
}
Or as already stated you can call PreferencesForm.ShowDialog() to make the form modal, in which case the user has to close the form before they can even interact with the main form again.
The method you use depends on if you want the user to be able to use the main form even if the preferences form is open.
If you're looking for 1 and ONLY 1, You probably want to implement the Singleton pattern for the Prefs class.

Categories