I have a dialog window with a listbox containing >3000 items that takes a long time to initially load. To load this dialog, I created an instance var dlg = new frmDlg(); and then when I need this dialog, I open it with dlg.ShowDialog(this); Although this reduced the number of time the listbox needs to be initialized, it still takes a long time to show the form as the dialog is unloaded from memory after the dialog closes, requiring the visual elements to be reloaded. Is there any way to keep this from happening? With a normal form, I would just hide the window instead of closing it, but this does not seem to work for dialog windows.
Add the following members to the frmDlg:
private bool keepHandle;
protected override void OnFormClosing(FormClosingEventArgs e)
{
keepHandle = e.CloseReason == CloseReason.UserClosing;
base.OnFormClosing(e);
}
protected override void DestroyHandle()
{
if (!keepHandle)
base.DestroyHandle();
}
This should prevent the dialog's handle from being destroyed when the dialog closed by the user.
Form1:
public partial class Form1 : Form
{
private Form2 reusable = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (reusable == null) reusable = new Form2();
reusable.ShowDialog(this);
switch (reusable.DialogResult)
{
case DialogResult.OK: MessageBox.Show("Ok clicked."); break;
case DialogResult.Cancel: MessageBox.Show("Cancel clicked."); break;
case DialogResult.None: MessageBox.Show("Form Closed."); break;
}
}
}
Form2:
public partial class Form2 : Form
{
private DialogResult dialogResult = DialogResult.None;
public new DialogResult DialogResult
{
get => this.dialogResult;
set => this.dialogResult = value;
}
public Form2()
{
InitializeComponent();
}
private void Form2_Shown(object sender, EventArgs e)
{
this.dialogResult = DialogResult.None;
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
}
private void button1_Click(object sender, EventArgs e)
{
this.dialogResult = DialogResult.OK;
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
this.dialogResult = DialogResult.Cancel;
this.Close();
}
}
^ Several caveats: you can no longer use the result from ShowDialog result, and you need to create your own DialogResult property, or just use a completely different / new property to represent how your dialog was hidden.
You also can't use the Button.DialogResult property anymore on any buttons, and you need to implement your own button click events to handle setting the dialog result.
This is all because of stuff that happens under the hood in the .net framework when you call ShowDialog result.
Also, Dmitry's example on using the e.CloseReason is valid too - you might want to allow closing for stuff like the application closing. That way you can also handle the FormClosed event and do any rapid cleanup you need to do before the application closes.
Related
private void button4_Click(object sender, EventArgs e)
{
LogoutQuestion log = new LogoutQuestion(this);
log.Show();
}
This is the code in the Menu Form. Basically what I want to do is to ask the user if he wants to leave the program, and if so to close the LogoutQuestion Form and the parent, Menu Form. Any ideas on how to accomplish that?
namespace Project
{
public partial class LogoutQuestion : Form
{
Form FormParent = null;
public LogoutQuestion(Form parent)
{
FormParent = parent;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
this.FormParent.Close();
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
The above is the whole LogoutQuestion Form I spoke of. Any help will be greatly appreciated. :-)
Make LogoutQuestion a dialog(log.ShowDialog();) This way you can also
retrieve the result of the users response, since this will return a
DialogResult.
With ShowDialog you make the form modal. This means that it is tied to the parent form that showed it. This is just like when you try to save a file in other windows programs. This also means that the user can't proceed with anything else, until this form is closed. This also gives you the option to use the results of the users actions when the form closes.
private void button4_Click(object sender, EventArgs e)
{
LogoutQuestion log = new LogoutQuestion();
DialogResult dr = log.ShowDialog();
if(dr != DialogResult.Cancel)
{
this.Close();
}
}
When I click a button a form is opened, but if the form is already open, then the app should display the message "Form already open!" and do nothing else.
My problem is, once I close the window [x] I can't open the form again.
Here's the code:
Form2 decript_form = new Form2();
private void button2_Click(object sender, EventArgs e)
{
if (!decript_form.Visible)
decript_form.Show();
else
MessageBox.Show("Form already open!");
}
When the "Close" button is pressed, you want it to just "hide" the form...you need to use e.Cancel to stop it going on and closing.
If you really really want to close the Form2 window instead of hiding it while your application is running....then call ReallyClose....so that the close isn't prevent (then create a new decript_form or null it out).
(Alternatively decript_form.Dispose() would force real closure too)
public partial class Form2 : Form
{
private bool m_bReallyClose = false;
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
if (!m_bReallyClose)
{
this.Visible = false;
e.Cancel = true;
}
}
public void ReallyClose()
{
m_bReallyClose = true;
this.Close();
}
}
public partial class Form1 : Form
{
Form2 decript_form = new Form2();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (!decript_form.Visible)
decript_form.Show();
else
MessageBox.Show("Form already open!");
}
private void button2_Click(object sender, EventArgs e)
{
decript_form.Dispose(); // or .ReallyClose();
decript_form = new Form2();
}
}
I assume that you talk about the [x] on Form2 being pressed. It that's the case you should handle the Closing event in Form2() and add
this.Hide();
to the handler. Even a closed window is still 'shown' until it is hidden.
class Form2
{
override protected void OnClosing(CancelEventArgs e)
{
Hide();
}
}
First of all, I am a newcomer to C# and programming in general. I've searched pretty thoroughly, but I can only find instances where someone wants to open another form and hide the one that the button was pressed on.
In this instance, I'm having issues with my program continuously running when I press the (X) on any form other than the main "Form1".The form-to-form navigation works fine. i.e.: clicking a button hides the main window and opens the appropriate form, and the "back" button on that form hides itself and shows (I guess another instance) of the previous "main" form. --I could probably use some guidance in that, too. lol
I wouldn't mind if it closed the entire application if the X was pressed, but I need to have the "X" present on all windows and all windows need to exit the entire app if the X is pressed. Any suggestions?
Thanks in advance,
Code:
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void btnTransaction_Click(object sender, EventArgs e)
{
Transaction transactionForm = new Transaction();
Form mainForm = this;
transactionForm.Show();
mainForm.Hide();
}
}
Transaction Form:
public partial class Transaction : Form
{
public Transaction()
{
InitializeComponent();
}
private void button4_Click(object sender, EventArgs e)
{
Form1 mainForm = new Form1(); //not sure if I'm doing this right..
this.Hide(); //I don't know how to "reuse" the original Form1
mainForm.Show();
}
}
I would recommend you create an MDI Container for this. Drag and drop a MenuStrip from the ToolBox to Form1 and then create a ToolStripMenuItem "form2" in MenuStrip.
Now you can call your form2 in form1 like this
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
IsMdiContainer = true;
}
Form2 frm2;
public void CreateMdiChild<T>(ref T t) where T : Form, new()
{
if (t == null || t.IsDisposed)
{
t = new T();
t.MdiParent = this;
t.Show();
}
else
{
if (t.WindowState == FormWindowState.Minimized)
{
t.WindowState = FormWindowState.Normal;
}
else
{
t.Activate();
}
}
}
private void form2ToolStripMenuItem_Click(object sender, EventArgs e)
{
CreateMdiChild<Form2>(ref frm2);
}
}
When by clicking ToolStripMenuItem you fire ToolStripmenuItem event , it will show Form2 as child in form1 i.e the mdi container and will be closed when you close form1.
public partial class Transaction : Form
{
Form1 _mainForm;
public Transaction(Form1 mainForm)
{
InitializeComponent();
_mainForm = mainForm;
}
private void button4_Click(object sender, EventArgs e)
{
this.Close(); //since you always create a new one in Form1
_mainForm.Show();
}
}
You can use the use Form.ShowDialog()
When this method is called, the code following (code below the 'ShowDialog()') it is not executed until after the dialog box is closed.
private void button4_Click(object sender, EventArgs e)
{
Form1 mainForm = new Form1();
this.Hide();
mainForm.ShowDialog();
this.Show();
}
You could use the ShowDialog() method that will require the user to interact with the new form before returning to the previous form. For instance you could try this:
public void btnTransaction_Click(object sender, EventArgs e)
{
using (var transactionForm = new Transaction())
{
this.Hide();
if (transactionForm.ShowDialog() == DialogResult.OK)
{
this.Show();
}
}
}
The DialogResult is something you can set on the TransactionForm like so:
private void button4_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
That's a pretty standard way of forcing interaction on a new form.
protected override void OnClosing(CancelEventArgs e)
{
this.Hide();
menu menu = new menu("administrator");
menu.ShowDialog();
this.Close();
}
//happy coding
I would like to make X control closing window to hide current display previous form.
In form1 I got:
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Tag = this;
form2.Show(this);
Hide();
}
and then when I click X I would like to show previous and hide the current.
You should not override Form.OnFormClosing() for just this. The Form.FormClosing event provides this functionality for you:
void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
// Prevent the user from closing this window, minimize instead.
if (e.CloseReason == CloseReason.UserClosing)
{
this.WindowState = FormWindowState.Minimized;
e.Cancel = true;
}
}
You can override OnFormClosing to do this.
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.WindowsShutDown) return;
// DO WHATEVER HERE
}
You have to keep track of your instanced forms.
// Program.cs
public static FormA Instance;
public static void Main()
{
Instance = new FormA();
Instance.Show();
}
Then:
// FormB.cs
private void button1_Click(object sender, EventArgs e)
{
Hide(); // Hide current...
Program.Instance.Show(); // Show previous...
}
I have a bunch of windows forms. Each form has "Back" and "Next" buttons for switching forms. For example, clicking "Back" on Form3 then we go to Form2. Then clicking "Next" button on Form2 then Form3 is shown.
Now my question is that if we click "Next" from the very beginning, it works smoothly. However if I click "Back" on Form3 then Form2 is displayed, then click "Next" on Form3 go to Form3. The code doesn't goto Form3_Load event.
What is wrong in my code?
public partial class Form3 : Form
{
Form2 FormPrev;
Form4 FormNext;
List<DataRow> drlist = new List<DataRow>();
DataTable dt = new DataTable();
public Form3(Form2 _FormPrev)
{
InitializeComponent();
this.FormPrev = _FormPrev;
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnNext_Click(object sender, EventArgs e)
{
ShowNext();
}
private void btnBack_Click(object sender, EventArgs e)
{
ShowPrev();
}
private void ShowNext()
{
if (FormNext == null)
FormNext = new Form4(this);
FormNext.Show();
this.Hide();
}
private void ShowPrev()
{
FormPrev.Show();
this.Hide();
}
private void Form3_Load(object sender, EventArgs e)
{
// blah blah.
}
Thanks.
A form's Load event is only fired when the form is invoked for the first time. If you subsequently hide the form and reshow it then this is not reloading the form so the form's Load event is not fired.
If you want to use an event to handle when the form is re-displayed then you should look at the following more suitable events:
Activated
Shown
VisibleChanged
Form Load event only gets fired before the form is shown for the first time.
You should use a different event, like maybe Form Activated or GotFocus.
That's a normal behaviour. Load is for load form, not for show. In your case you try to show hided form. If you want to use
form.Show()
than use not a
form.Hide()
but
form.Close()
UPD:
Code should be:
public partial class Form3 : Form
{
List<DataRow> drlist = new List<DataRow>();
DataTable dt = new DataTable();
public Form3()
{
InitializeComponent();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnNext_Click(object sender, EventArgs e)
{
ShowNext();
}
private void btnBack_Click(object sender, EventArgs e)
{
ShowPrev();
}
private void ShowNext()
{
Form4 formNext = new Form4();
formNext.Show();
this.Close();
}
private void ShowPrev()
{
Form2 formPrev = new Form2();
formPrev.Show();
this.Close();
}
private void Form3_Load(object sender, EventArgs e)
{
// blah blah.
}
}
But there is a problem with such colutions - you shouldn't close your main form.