I want to know if there is any event when you click on the rest of the screen and not the Windows Form the Form closes. Is it because of the ShowDialog()?
My Main Form is just with a notifyIcon and when I click it I call Form1.ShowDialog();
Main.cs:
private void ShowForm1(object sender, EventArgs e)
{
form1.Left = Cursor.Position.X;
form1.Top = Screen.PrimaryScreen.WorkingArea.Bottom - form1.Height;
form1.ShowDialog();
}
Form1.cs:
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = "Test";
}
You need to run the dialog box non-modally, not modally. Think about it, when you run it modally, the dialog box takes over the UI and plays games with mouse-clicks elsewhere, preventing you from running. You don't want it to be modal anyway.
I created a simple Windows form with a button that includes this handler to open a small AutoCloseDialog form I created (and populated with a few controls):
private void button1_Click(object sender, EventArgs e)
{
var dlg = new AutoCloseDialog();
dlg.Show(this); //NOTE: Show(), not ShowDialog()
}
Then, in the AutoCloseDialog form, I wired up the Deactivate event. I did it in the designer (where this code is generated):
this.Deactivate += new System.EventHandler(this.AutoCloseDialog_Deactivate);
Finally, here is the handler for the Deactivate event.
private void AutoCloseDialog_Deactivate(object sender, EventArgs e)
{
this.Close();
}
I think this does what you are asking.
Yes, you can create a similar function like this, which closes the Form if the Form lost focus (in Form1.cs)
public void Form_LostFocus(object sender, EventArgs e)
{
Close();
}
and then you add the LoseFocus EventHandler (in Form1.Designer.cs):
this.LostFocus += new EventHandler(Form_LostFocus);
Related
I have a Windows Forms Add-in on Revit using Revit-API and C#. The project contains two forms ( Main form and About form). the About form opens by a button click in the main form. The problem is that when I try to close the About form through the Control box or by using a button inside it About.ActiveForm.Close() it automatically closes all the Forms. I tried About.ActiveForm.Hide() and also doesn't work. Also, I tried to link the Cancel Button of the about form to that button and it didn't work.
Code of initiating the About form
private void button3_Click(object sender, EventArgs e)
{
About abt = new About();
abt.ShowDialog(this);
}
Code of Closing the About Form
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}
I also tried this for the closing part
private void button3_Click(object sender, EventArgs e)
{
Close();
}
and I tried this also for the initiating part
private void button3_Click(object sender, EventArgs e)
{
About abt = new About();
abt.ShowDialog();
}
I know you will be thinking "Not again this question", as I found like a hundred results when I searched for it. But when I put in the code as described on the pages here, it just minimizes to right above the start menu.
This is the code I use (I added a message box to see if the code gets triggered, but the message box never pops up):
private void Form1_Resize(object sender, EventArgs e)
{
MessageBox.Show("Works1");
if (WindowState == FormWindowState.Minimized)
{
this.Hide();
}
}
Because I don't know if it links to Form1 or Form, I have tried both, to no avail.
private void Form_Resize(object sender, EventArgs e)
{
MessageBox.Show("Works");
if (WindowState == FormWindowState.Minimized)
{
this.Hide();
}
}
Now, when you double click on the Form, it puts this line in the Form1.Designer.cs:
this.Load += new System.EventHandler(this.Form1_Load);
Do I need a similar line to trigger the minimize event?
As you can see, I am completely lost :)
Oh, and it doesn't minimize to the taskbar, as I am using the following code to hide the form on run:
protected override void OnLoad(EventArgs e)
{
Visible = false; // Hide form window.
ShowInTaskbar = false; // Remove from taskbar.
base.OnLoad(e);
}
You need the event
private void Form1_Resize(object sender, EventArgs e)
{
}
Creating Event Handlers on the Windows Forms Designer
Add a NotifyIcon component to your Form. Make sure you set an icon via the properties pane otherwise it will be invisible.
Create an event handler for the form's Control.SizeChanged event. In that event handler place the following code:
sample code:
private void MainForm_SizeChanged(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
ShowInTaskbar = false;
}
And then to make the form visible again the NotifyIcon.MouseDoubleClick event handler you can place the following code:
private void trayIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
WindowState = FormWindowState.Normal;
ShowInTaskbar = true;
}
The basic thing you need to know is events. Events are triggered when certain things happen to your form (or any control). For example, when the form is resized, or loaded, or clicked, an event is raised. You can hook into this event to execute your own code when the event happens.
In your case you want to execute code to minimize the form, on the event that the form is resized. So you need to hook your method to the resize event. The name of your method is not relevant, so let's use a better name:
private void HideWhenMinimized(object sender, EventArgs e)
{
MessageBox.Show("Works1");
if (WindowState == FormWindowState.Minimized)
{
this.Hide();
}
}
To hook your HideWhenMinimized method into the Resize event of the form, you have to do it like this:
this.Resize += new System.EventHandler(this.HideWhenMinimized);
If you add that line of code in the form's constructor or Load event, then your code gets called as soon as the form is resized.
I have two forms:
MainForm
SettingsForm
As you can imagine, MainForm uses values such as Properties.Settings.Default.Path and SettingsForm should be able to configure such a value on runtime.
But somehow SettingsForm: Properties.Settings.Default.Save(); takes effect just after application restart, although I'm reloading those settings in MainForm: Properties.Settings.Default.Reload();
I have this so far:
In MainForm.cs:
// Handles "config button click" => display settings form
private void configStatusLabel_Click(object sender, EventArgs e)
{
SettingsForm form = new SettingsForm();
form.FormClosed += new FormClosedEventHandler(form_FormClosed);
form.Show();
}
// Callback triggered on Settings form closing
void form_FormClosed(object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.Reload();
}
// There are another methods called after form_FormClosed is triggered, for example
// StremWriter = new StreamWriter( Properties.Settings.Default.Path)
And SettingsForm.cs:
// Triggered on "Save button click" in Settings form, after changing values
// Example: Properties.Settings.Default.Path = "C:\\file.txt"
private void saveButton_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Save();
Close();
}
What am I missing? How can I achieve "on demand change"?
More on program flow
In main form, there are several buttons which will trigger function such as ReloadLog() which uses Properties.Settings.Default.Path. So at the end I'm having functions executed at this order:
ReloadLog(); // Triggered by the user (several times)
// This reloads contents of log, say C:\\main.log
configStatusLabel_Click(); // User hit "configure button", there are two active forms
// SettingsForm is now displayed too
// At this point ReloadLog() may be called in MainForm many times
// Meanwhile in SettingsForm:
Properties.Settings.Default.Path = PathTextBox.Text;
private void saveButton_Click(object sender, EventArgs e) // User hit save button
{
Properties.Settings.Default.Save();
Close(); // This will trigger form_FormClosed in main form
}
// Now you would expect that following line will open D:\\another.log
ReloadLog();
// But it still uses original config, however when I turn app off and on again, it works
private void configStatusLabel_Click(object sender, EventArgs e)
{
SettingsForm form = new SettingsForm();
form.FormClosed += new FormClosedEventHandler(form_FormClosed);
form.FormClosed += (s, e) => { MethodThatAppliesTheSettings(); };
form.Show();
}
I have a button on the first form, that when clicked opens a second form and closes the first.
However, no mater what I do 'both' forms close.
This is the button on the first form:
private void btnReports_Click(object sender, EventArgs e)
{
Form f2 = new frmForm2();
f2.Show();
}
And this is the code in the Load event of the second form
private void frmReports_Load(object sender, EventArgs e)
{
Application.OpenForms["frmForm1"].Close();
}
I also tried
private void btnReports_Click(object sender, EventArgs e)
{
Form f2 = new frmForm2();
f2.Show();
this.Close();
}
You probably have this as startup:
Application.Run(new frmForm1());
If frmForm1 is closed then the application stops. You should hide the form using frmForm1.hide();
Take a look at the following Application.Run(ApplicationContext) method. There is an example on how to set up your application so that it will only exit when the last form is closed, not when the main form is closed.
if you run this snippet of code(put it in form1) in a fresh new winform app with 2 forms
private void Form1_Load(object sender, EventArgs e)
{
Form2 newForm = new Form2();
Button b = new Button();
newForm.Controls.Add(b);
b.Click += new EventHandler(click);
this.Show();
newForm.ShowDialog();
}
private void click(object sender, EventArgs e)
{
((Form)((Control)sender).Parent).ShowInTaskbar = false;
}
and you click on the button on the new form(should be form2), form2 will close.
How to keep it open?
It is not possible. I actually filed a bug report about it at Microsoft's feedback site but they flipped me the bird on it.
Admittedly, it is a tricky problem to solve, changing the property requires Windows Forms to recreate the window from scratch because it is controlled by a style flag. The kind you can only specify in a CreateWindowEx() call with the dwExStyle argument. Recreating a window makes it difficult to keep it modal, as required by the ShowDialog() method call.
Windows Forms works around a lot of User32 limitations. But not that one.
You keep it open by setting ShowInTaskbar to false before you ShowDialog();
private void Form1_Load(object sender, EventArgs e)
{
Form2 newForm = new Form2();
Button b = new Button();
newForm.Controls.Add(b);
b.Click += new EventHandler(click);
this.Show();
// add this line of code...
newForm.ShowInTaskbar = false;
newForm.ShowDialog();
}
private void click(object sender, EventArgs e)
{
((Form)((Control)sender).Parent).ShowInTaskbar = false;
}
Or just don't make the second form modal. This works also.
private void Form1_Load(object sender, EventArgs e)
{
Form2 newForm = new Form2();
Button b = new Button();
newForm.Controls.Add(b);
b.Click += new EventHandler(click);
this.Show();
newForm.Show();
}
I don't know the specific mechanism here, but clearly what is happening is that changing the flag (which actually changes one or more WS_EX_xxx window styles) is causing the modal pump of ShowDialog() to exit. This, in turn is causing you to (finally!) exit Form1_Load and then your newForm goes out of scope and is destroyed.
So your problem is a compbination of ShowDialog() and the fact that you aren't prepared for ShowDialog() to ever exit.
Now a modal for shouldn't show up with a taskbar icon in the first place, there really should be only 1 taskbar icon for an application and all of it's modal forms, since when a modal form is running, the main form is disabled anyway. When the main form is minimized, all of the modal forms that it owns will be hidden, etc.
So if you really want this second form to be modal, you shouldn't give the user the ability to give it a taskbar icon. If using ShowDialog() was just test code, then don't worry about it. The problem will go away when the form runs on the main application pump.
Your question isn't very clear to me. Anyway, the newForm form is displayed as a modal dialog, which means that it blocks the user from working with the parent form until it is closed. Modal dialogs usually have some buttons that automatically close them returning either OK or Cancel to the calling form (as a return value of ShowDialog). This is done using the DialogResult property, so if this property is set for your button, this may be a reason why the modal form closes when you click on it.
If you want to show more forms in a way that allows the user to work with both of them, you'll need to use modeless dialog. Here is a good overview article on MSDN.
how... my... this is an ugly hack
this work
private void Form1_Load(object sender, EventArgs e)
{
Form2 newForm = new Form2();
Button b = new Button();
newForm.Controls.Add(b);
b.Click += new EventHandler(click);
newForm.FormClosed += new FormClosedEventHandler(form2_closed);
newForm.FormClosing += new FormClosingEventHandler(form2_closing);
this.Show();
do
{
newForm.ShowDialog();
} while (newForm.IsDisposed == false );
}
private void click(object sender, EventArgs e)
{
((Form)((Control)sender).Parent).ShowInTaskbar = !((Form)((Control)sender).Parent).ShowInTaskbar;
}
private void form2_closed(object sender, FormClosedEventArgs e)
{
((Form)sender).Dispose();
}
private void form2_closing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.None)
e.Cancel = true;
}