I have two forms, I open and showdialog the second form like this:
Recieving_Stock_Form f = new Recieving_Stock_Form();
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
f.ShowDialog();
Now when I close the second form I want to trigger an event on the first form
E.G
void txtStockCount_TextChanged(object sender, EventArgs e)
Any ideas where I can look up about this or how to do it?
Thanks
in Form1, assuming that your code is this
Recieving_Stock_Form f = new Recieving_Stock_Form();
You can add the code
f.Form_Closing += ExampleHandler;
ExampleHandler(object sender, FormClosingEventArgs e)
{
//Do stuff
}
I'd rather not had cheated with the form; instead, I suggest assigning the value from Recieving_Stock_Form to txtStockCount:
using (Recieving_Stock_Form f = new Recieving_Stock_Form()) {
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
// == DialogResult.OK - let user have a chance to cancel his/her input
if (f.ShowDialog() == DialogResult.OK) {
//TODO: put the right property here
txtStockCount.Text = f.StockCount.ToString();
}
}
The ShowDialog is modal so it will block executiong, so when you close it, the next thing is executed.
You can do this:
Recieving_Stock_Form f = new Recieving_Stock_Form();
f.Username = Username;
f.Role = Role;
f.Date = monthCalendar1.SelectionStart.ToString(#"yyyy\/MM\/dd");
f.ShowDialog();
// it will continue here when the form is closed.
txtStockCount_TextChanged(this, EventArgs.Empty); // or assign the variable directly.
There is two events that you can handle - FormClosed and FormClosing, depending on your decision.
f.FormClosed += f_FormClosed;
private void f_FormClosed(object sender, FormClosedEventArgs e)
{
//Call your function or do whatever you want
}
Related
I am developing an application which requires loggging in.
I've developed the following forms:
- frmMain
- frmLogon
Form main launches when bootstrapping the windows forms application. In the "Shown" event of form main the FrmLogon form is shown as a dialog.
However when automatically setting the DialogResult to OK the form won't close, the program only works when manually hitting the "Logon" button, which triggers the exact same functionality.
Ive tried to Close() the form logon, but this leaves me with an System.ObjectDisposedException.
Any suggestions?
FrmMain.CS
private void OnFormShown(object sender, EventArgs e)
{
OnClickMenuLogon(sender, e);
}
private void OnClickMenuLogon(object sender, EventArgs e)
{
if (IsLoggedOn())
{
G.LogOff();
User = null;
OnLoggedOff();
}
else
{
FrmLogon logon = new FrmLogon(G, true);
DialogResult result = logon.ShowDialog();
if (result == DialogResult.OK)
{
User = logon.User;
_hostName = User.Name + " # " + (String.IsNullOrEmpty(logon.HostName) ? Environment.MachineName : logon.HostName);
OnLoggedOn();
}
}
}
FrmLogon.CS
private void OnLogOnSuccess(object sender, LoggedOnEventArgs e)
{
tbStatus.Text = $"[{DateTime.Now.ToString("HH:mm:ss")}]: Successfully logged on.\r\n" + tbStatus.Text;
User = _g.LoggedUser;
HostName = tbHost.Text;
DialogResult = DialogResult.OK;
}
Edit: When using
this.DialogResult = DialogResult.OK;
this.Close();
the following exception occurs:
Exception screenshot
Instead of just using
DialogResult = DialogResult.OK;
Use
this.DialogResult = DialogResult.OK;
this.Close();
this.Close() will close your second form and return it's current DialogResult.
UPDATE 1
Other way is to add some invisible button to the Dialog Form, set it as AcceptButton and perform click on it in this way:
Button bt = new Button();
bt.Click += new EventHandler((sender1,e1)=> {
this.DialogResult = DialogResult.OK;
});
bt.FlatStyle = FlatStyle.Flat;
bt.FlatAppearance.BorderColor = BackColor;
bt.FlatAppearance.MouseOverBackColor = BackColor;
bt.FlatAppearance.MouseDownBackColor = BackColor;
this.Controls.Add(bt);
this.AcceptButton = bt;
bt.PerformClick();
Problem is solved, the attempt to logon was made in the FrmLogon's constructor which caused the DialogResult to be set before the form was initialized. After implementing the "Shown" event and calling the functionality from there in FrmLogon the problem was solved. Thank you all.
I'm trying to create a simple login screen, which has 2 textboxes and 1 button. When strings i've insterted in the first textbox (username) and the second textbox (password) matches the strings i've defined before, the buttons Enabled propertie should become True and when clicked, it should open another form, here's the code i've written so far:
public partial class LogInScreen : Form
{
public LogInScreen()
{
InitializeComponent();
string lietotajvards = "user";
string parole = "user";
if (textBox1.Text == lietotajvards && textBox2.Text == parole)
{
button1.Enabled = true;
}
else
{
button1.Enabled = true;
}
}
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
this.Hide();
f1.Show();
}
}
The thing is that with my code it doesn't work as expected and the button is enabled all the time. Where's the problem?
Your code will only execute once when the form is initialized, you have to make use of a textchanged event on textbox1 and textbox2, thereafter you can use the code you wrote to check if the button needs to be enabled. In the else you must disable the button.
Text changed event handlers:
void textBox1_TextChanged(object sender, EventArgs e)
{
handleLoginButton();
}
void textBox2_TextChanged(object sender, EventArgs e)
{
handleLoginButton();
}
Enable/disable button:
private void handleLoginButton(){
string lietotajvards = "user";
string parole = "user";
if (textBox1.Text == lietotajvards && textBox2.Text == parole)
{
button1.Enabled = true;
}
else
{
button1.Enabled = false;
}
}
The constructor only runs once for the form, you need to handle the text changed events for the input controls and then re-evaluate your condition again.
Also it should go without saying (although it is being said here) that this is a terrible way to handle logging in to an application.
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