.NET WinForm GC question - c#

Is this code clean?
private void button1_Click(object sender, EventArgs e)
{
frmCustomDialog f = new frmCustomDialog();
if(f.ShowDialog() == DialogResult.OK)
TextBox1.Text = f.MyCustomProperty;
}
Do you need to close or dispose the form f or anything? Or is it automatically garbage-collected?
Thank you.

Yes, you should dispose of the form:
private void button1_Click(object sender, EventArgs e)
{
using (frmCustomDialog f = new frmCustomDialog())
{
if(f.ShowDialog() == DialogResult.OK)
{
TextBox1.Text = f.MyCustomProperty;
}
}
}
ShowDialog() doesn't dispose of the form as you can reuse it and show it again. If you don't need to do this, you should just dispose it yourself.
From the docs of ShowDialog():
Unlike modeless forms, the Close
method is not called by the .NET
Framework when the user clicks the
close form button of a dialog box or
sets the value of the DialogResult
property. Instead the form is hidden
and can be shown again without
creating a new instance of the dialog
box. Because a form displayed as a
dialog box is not closed, you must
call the Dispose method of the form
when the form is no longer needed by
your application.

If you are showing form as dialog form (which you are since you're calling it with the form.ShowDialog()), then you have to manually dispose of the object, because Close method of the form is not automatically called when closing the form (the form is hidden instead).
You can read more here.

Related

how to open a form from another form in c#

i am writing a code for serial key registration.
if the serial key entered by the user is correct then anothr form must open and the present form must close.
please go thought the code.
namespace ExtTrigger
{
public partial class Activation : Form
{
public Activation()
{
InitializeComponent();
}
private void ActivateButton_Click(object sender, EventArgs e)
{
String key;
key = string.Concat(textBox1.Text,textBox2.Text,textBox3.Text,textBox4.Text);
if (key == "1234123412341234")
{
Properties.Settings.Default.Registered = true;
MessageBox.Show("hurray", "", MessageBoxButtons.OK);
Form1 f1= new Form1();
f1.ShowDialog();
this.Close();
}
else
MessageBox.Show("No Match", "", MessageBoxButtons.OK);
}
private void Activation_Load(object sender, EventArgs e)
{
}
}
my problem is: On clicking on ActivateBotton, Form1 opens but the present form doesnot close.
i have read in few threads that in VB we can change the property: ShutdownMode.
How can we do that in c#?
f1.ShowDialog(); blocks the call, it doesn't go to the next line until that new form has been closed.
An option would be to use:
f1.Show();
Show doesn't block the call, it passes to the next statement. It will not wait for the new form to be closed.
since you have show the second form as f1.ShowDialog() so first one remain open untile second one close, try this
Form1 f1= new Form1();
f1.Show();
this.Close();
The following code should do the trick:
using(Form1 f1 = new Form1())
{
this.Hide();
DialogResult result = f1.ShowDialog();
if(result == DialogResult.OK)
{
this.Show();
}
}
You create your new form within the using-block, then you hide your main form(or the form you are in at the moment) create a DialogResult that gets set by the newly opened form and open this form. Now you can set the results you want to check for inside of your new form and if everything went well inside of you new form you set the DialogResult to OK via:
this.DialogResult = DialogResult.OK;
Now back in our first form you check for the DialogResult and if it is okay you show your main form again. If it was not okay you could just reopen the 2nd form and let the user try again.
Opening a new form is very simple, but the way you do it really depends on your need.
Case 1: I would like to freeze/ block the calling form on secondary form call
In this case you should be using secondaryFormObj.ShowDialog();
Of course, when using this technique your called form, which now acts as a dialog, should "return" an answer to its caller parent on closure.
For example:
private void SecondaryForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// Just a dummy code example.
// Always returns Yes result on form closure
this.DialogResult = System.Windows.Forms.DialogResult.Yes;
}
For more help and examples on this manner you can use MSDN:
DialogResult - MSDN
Case 2: I would like to have both forms responding at the same time
In this case you basically need to call secondaryFormObj.Show();
If you want the caller form to be hidden on secondary form call, just
invoke this.Hide();
after the call to secondaryFormObj.Show(); in the caller class.
You can also close the caller form using this.Close(); as long as the caller form is not the application's main form.
... And remember
Always make sure you initialized the secondary form object before
invoking it with either secondaryFormObj.Show(); or
secondaryFormObj.ShowDialog();
Initializing a form is done the same way like every typical object using the
new operator.
For example: secondaryFormObj = new Form();
Hopes this helps. Happy coding!

Items in checklistbox deleted after form closes

I have a simple c# winform and I'm trying to add a string to it.
e.g.
checklistbox1.Items.Add("string");
the problem is that after I close the form and run the program again, my added string is deleted from the checklistbox and I have to enter it again.
When you close the form, the members associated with it are removed as well. If you want it to be saved, you need to use a method that well save the data for you, such as XML, txt doc, or even a database, depending on the lifespan of the information you want to keep.
If it is only needed while the program is running, you may look into having the information stored in a member in the mainform rather than only just the form with the checklistbox.
Add a public List property to your form.
Create a second ctor for your form and inside your second ctor code
write:
public YourForm(List<string>() strings)
{
foreach(var item in strings)
{
checklistbox1.Items.Add(item);
}
}
You don't have to unload the form when closing. Let the parent form - I assume this is launched from another form - do the unloading/disposing of all the child forms instead. The trick is to make it appear to the user that you're closing the form. Let's say the form containing the checklist is Form2, the function that loads Form2 from the parent form will look like this:
Form2 _form2 = null;
private void button1_Click(object sender, EventArgs e)
{
if (_form2 == null)
{
_form2 = new Form2();
}
_form2.Show();
}
And in the Form2, handle the Closing event like this:
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
Hide();
}
And finally, in the parent form Closing event, you can dispose Form2
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (_form2 != null)
{
_form2.Dispose();
_form2 = null;
}
}
If you need to have the same set of values for all instances of Form2, then you can use Singleton pattern. That's another discussion :)

Access Form - instantiate it once

After closing a form, I can't access it anymore, because the object does not exist anymore.
Is there a way to avoid this kind of behaviour, without initiating the object everytime I perform an event?
This is the first Form called status, it's not the only one I need to create, that's why Iam asking.
This does not work: After closing the form and click on the menu item I get an reference error "Object does not exist", and therefor can't be accessed.
public partial class Main : Form
{
StatusForm statusForm = new StatusForm();
public Main()
{
InitializeComponent();
statusForm.MdiParent = this;
}
private void statusToolStripMenuItem_Click(object sender, EventArgs e)
{
statusForm.Show();
}
private void Main_Load(object sender, EventArgs e)
{
statusForm.Show();
}
}
If you use Close to close a form, it is unusable after that point. You have to create a new one.
However, if you want a persistent Form object, just call Form.Hide instead. This hides the form but leaves it "open".
MSDN notes this as well:
When the Close method is called on a Form displayed as a modeless
window, you cannot call the Show method to make the form visible,
because the form's resources have already been released. To hide a
form and then make it visible, use the Control.Hide method.

Closing and Opening Forms

What is the best way to close a form and get to another form.
At present I have a Main Form and then two forms:
I want to know how to close one form and open another form efficiently.The two times I did it had a slight different outcome:
The main form in my application is just the introduction which will load some Company Logo and show a progress bar which will then take it to a log-in form, where in I have a log-in button, from where the actual application will open.
I have some questions.In the Main Form I have added this code:
private void Form1_Load(object sender, EventArgs e)
{
int i;
for (i = 0; i <= 100; i++)
{
progressBar.Value = i;
label1.Text = "Please wait while Refresh loads up...";
}
}
private void progressTimer_Tick(object sender, EventArgs e)
{
this.Close();
}
private void MainForm_Deactivate(object sender, EventArgs e)
{
Form form = new FirstForm();
form.ShowDialog(this);
}
1) This works fine, just that the new form that opens up is at the task bar and is not in the center of the screen(as I have set it's property).How do I fix this?
In the First Form I have added this code:
private void loginButton_Click(object sender, EventArgs e)
{
using( ERPQueries eq = new ERPQueries())
{
int? count = eq.CheckEmployee(userTextBox.Text,passwordTextBox.Text);
if (count == 1)
{
//testLabel.Text = "Ok";
this.Close();
Form form = new SecondForm();
form.ShowDialog(this);
}
else
{
testLabel.Text = "Invalid username or password!";
}
}
}
2) Here the next Form pops up in the center of the screen.I want to know how is it different from the first case, as I have used showDialog() in both the cases?
3) Also in the first case my Main Form Disappears, whereas in the second case the First Form is still visible in the background and disappears only after closing the SecondForm.
I'm sure I'm doing a lot of mistakes, my code is flawed.Please help.This is the first time I'm making an application with multiple forms.
Edit:
When I use Show() instead of ShowDialog() I don't see the new form.Am I missing something?
I tried this.Dispose() instead of this.Close().In the first case it works fine.In the second case, it disposes all the forms.
try:
form.Show();
not
form.ShowDialog(this);
which is what makes it modal.
ShowDialog() is blocking call, so if in one Form's deactivate event you call ShowDialog() of another, your parent form will not yet finish it deactivating.
Like a suggesion I can give you create a collection/stack of forms you want to manage and give control over it to a FormManager class, where you implement whatever logic you want and can call either ShowDialog() or Show(). In other words bring out forms Show/Hide management out forms itself.
Regards.

public DialogResult ShowDialog() help!

I have two forms.
The first form is the mainForm, this never goes anywhere.
On opening the second form (saveForm), it will display over the top.
When i close this form, I want a certain piece of code in the mainForm to run.
I assume this is the correct way to get this to happen?
The code on saveForm when I close and return to the mainForm:
private void btnSaveDetails_Click(object sender, EventArgs e)
{
Delivery d = new Delivery(txtNameBox.Text, txtAddressBox.Text, txtDayBox.Text, txtTimeBox.Text, txtMealBox.Text, txtInstructionsBox.Text, txtStatusBox.Text);
mainForm.myDeliveries.Add(d);
this.Close();
}
Any ideas?
You can use the DialogResult returned to effect some change in your application. For example, if you provided the user with a dialog asking whether or not they want to delete all files and they respond by clicking the Yes button on your dialog, you would then delete the files.
More information about how to use DialogResult and ShowDialog vcan be found here: DialogResult
UPDATE: If the code you posted is from your "child" form, then what you've done so far is probably fine, BUT, you still need to provide a DialogResult on that form to communicate to mainForm that something was done. For example, you could do the following before this.Close():
this.DialogResult = DialogResult.OK;
Then, in the code after the call to childForm.ShowDialog(), check the DialogResult. If it's equal to DialogResult.OK, then you can perform whatever task you need to that indicates the user clicked OK.
(And, on a side note, Dispose() is not called when you use ShowDialog(); you'll need to clean things up yourself, if necessary.)
You have to set the DialogResult property of you dialog form. Either explicitly in code or by assingning the dialog result to a button on your form.
private void btnSaveDetails_Click(object sender, EventArgs e)
{
Delivery d = new Delivery(
txtNameBox.Text, txtAddressBox.Text, txtDayBox.Text,
txtTimeBox.Text, txtMealBox.Text, txtInstructionsBox.Text,
txtStatusBox.Text
);
mainForm.myDeliveries.Add(d);
this.DialogResult = DialogResults.OK;
}
No need to call Close() setting this.DialogResult does that for you if you called the dialog using ShowDialog().
On calling the form you have to do the following:
var frm = new MyForm();
if (frm.ShowDialog() == DialogResults.OK) {
// do what you want to do on success.
}

Categories

Resources