Interaction between forms in WinForms application, c# - c#

guys!
I've got 2 forms in application - working form (frmMain) and form of settings (frmSettings).
There are two buttons on frmSettings - Save and Cancel. In frmMain I use the following approach to show the frmSettings:
private void btnSettings_Click(object sender, EventArgs e)
{
frmSettings = new SettingsForm();
frmSettings.ShowDialog();
// ...
}
The problem is I don't know, how to detect, which button was pressed on the frmMain - Save or Cancel. The further logic of the program depends on this fact. I need something like this:
private void btnSettings_Click(object sender, EventArgs e)
{
frmSettings = new SettingsForm();
frmSettings.ShowDialog();
if(/* frmSettings.SaveButton.WasClicked == true */)
{
InitializeServices();
}
// ...
}
Please, give me an advice, how to implement such kind of interaction between forms. Better without using global variables for saving buttons state.
Thanks beforehand.

ShowDialog returns a DialogResult object that allow you to know that. You have to:
On Save Button's click event, set this.DialogResult to DialogResult.OK
On Cancel Button's click event, set this.DialogResult to DialogResult.Cancel
private void btnSettings_Click(object sender, EventArgs e)
{
frmSettings = new SettingsForm();
if(frmSettings.ShowDialog() == DialogResult.OK)
{
InitializeServices();
}
//.......
}
Edited to manage the DialogResult as #tsiorn's answer: setting form's DialgoResult insted of setting that property on each button.

You chould use DialogResult to handle this. On your form settings window, you can set the result as so:
protected void btnSave_Click(object sender, EventArgs e) {
DialogResult = System.Windows.Forms.DialogResult.OK
this.close;
}
protected void btnCancel_Click(object sender, EventArgs e) {
DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.close;
}
Then ...
private void btnSettings_Click(object sender, EventArgs e)
{
frmSettings = new SettingsForm();
frmSettings.ShowDialog();
if(frmSettings.DialogResult == DialogResult.OK)
{
// save
InitializeServices();
}
// ...
}

Start with an enumeration of the possible values:
public enum ExitMethod
{
Other, //this should be first, as a default value
Save,
Cancel,
Error
}
Then make a property on SettingsForm of that type:
public ExitMethod ExitMethod { get; private set; }
In SettingsForm's save/exit methods set that property to the appropriate enum value, and in the main form you can read that property value.

in the frmSettings window you handle the Click events on the buttons. Then set the dialog result:
void frmSettings_Save_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
void frmSettings_Cancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
in the main form you do something like this to capture and evaluate the result:
DialogResult answer = frmSettings.ShowDialog();
if (answer == DialogResult.OK)
{
...
}
Additional information and usage can be found here:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.dialogresult.aspx

Related

How to stop windows form from closing but hide upon clicking the X?

I'm trying to have a click event that will open another form. I don't want the user to be able to close this window because I get the following exception when the click event is executed again.
System.ObjectDisposedException: 'Cannot access a disposed object.
Object name: 'Form2'.'
I'm not sure if I'm implementing this correctly or there's a better way of doing this.
Form1
public Form2 f = new Form2();
private void Btnsearch_Click(object sender, EventArgs e)
{
f.Show();
}
Form2
private bool allowClose = false;
private void Btnclose_Click(object sender, EventArgs e)
{
allowClose = true;
this.Hide();
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
if (!allowClose)
e.Cancel = true;
}
Subscribe to Form.OnClosing and set the Cancel property on the event args that are passed to the handler. This will tell the runtime to cancel the close event.
Since the event is getting canceled, you'll have to hide the form yourself (using Hide(), of course).
private void Form1_Closing(Object sender, CancelEventArgs e)
{
this.Hide();
e.Cancel = true;
}
The instance of form2 should be created within the event
private void Btnsearch_Click(object sender, EventArgs e)
{
Form2 f = new Form2();
f.Show();
}
There are a couple of ways to approach this.
It's generally more efficient, in the FormClosing event, to hide the form and cancel the event, but this can require extra logic.
Unless you have some expensive code that needs to run when the form is created, this probably doesn't matter, and it'll be easier to simply allow the form to close normally.
Either way, all you particularly need to do, is throw some safeguards into the btnSearch handler, so that it can appropriately respond to the state of form f;
public Form2 f;
public void BtnSearch_Click(object sender, EventArgs e)
{
if (f == null || f.IsDisposed || f.Disposing) f = new Form2(...);
f.Show();
}

Disable closing of a certain WinForm

I'd like to know if there's a possible solution (I hope there is) to my problem. I have two forms, the Login Form and the Main Form. I'd like to know if there's a way to disable closing of the Main Form and only allow closing when I sign out (which redirects the user back to the Login Form) and only allow closing when Login Form is active. Sorry for my bad english.
I tried using the event below, yes it stops me from closing the main form but when I signed-out it did the same to my Login Form which I didn't want to happen. Is there any way to do this?
private void Form1_Closing(object sender, CancelEventArgs e)
{
e.Cancel = true;
}
I suppose that you are using LoginForm like dialog (ShowDialog), Use DialogResult.Ok only when user logs successful
....
private voif logoutButton_click(object sender, EventArgs e)
{
_logged = false;
}
.....
private void loginButton_click(object sender, EventArgs e)
{
LoginForm _loginForm = new LoginForm();
if(_loginForm.ShowDialog() == DialogResult.Ok)
{
_logged = true;
}
}
......
private void Form1_Closing(object sender, CancelEventArgs e)
{
if(!_logged)
e.Cancel = true;
}

How can I use Enter to call event handler?

I have a textBox and search button, I would ask about how can I make the user can click Enter to start searching without need to go and click the search button?
This would be best practice
private void txtSearch_Enter(object sender, EventArgs e)
{
AcceptButton = btnSearch;
}
private void txtSearch_Leave(object sender, EventArgs e)
{
AcceptButton = null;
}
The Form has a property called "AcceptButton" that identifies a button that should be associated to the "Enter" keypress. Its considered the "default action" for the form.
More info here:
Windows Form - AcceptButton property
If you want to use something other than Enter/Return, you could also try:
private void EnterKeyAction()
{
// Search...
}
private void btnEnter_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return)
EnterKeyAction();
}
private void btnEnter_Click(object sender, EventArgs e)
{
EnterKeyAction();
}

user input and acceptance inside a function

My function accepts user input and then do somework when user clicks ok.
private void cannyToolStripMenuItem_Click(object sender, EventArgs e)
{
canny();
}
private void canny()
{
// get user input
// if user clicks ok
if (ok button is clicked)
{
messagebox.show(" you clicked ok")
//
//do dome work
//
}
}
But I can't see any messagebox. What I am missing.
private void ok_Click(object sender, EventArgs e)
{
// should I add here some thing
}
what i am missing.
regards,
I think what you are trying to achieve is to get the result from a dialog box. If that is the case you want to do the following:
private void ShowDialogAndDoSomethingBasedOnTheResult()
{
DialogResult result = MessageBox.Show(
"Dialog text",
"Caption to go in title bar",
MessageBoxButtons.OK);
if (result == DialogResult.OK)
{
//Do work
}
}
See http://msdn.microsoft.com/en-gb/library/0x49kd7z.aspx for more examples.
Well, yes, you do:
private void ok_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Ok;
}
Which closes the dialog, it will only stay running as long as its DialogResult property is None. It isn't strictly necessary, you can also use the designer. Change the button's DialogResult property, now you don't need to write the code. That is however not often appropriate, you usually want to check if the user provided all the information you require. Ymmv.

Why do buttons need to be pressed twice to work in this modal dialog?

I have this C# code:
public partial class Continue : Form
{
public Continue(string colourName)
{
InitializeComponent();
lblMessage.Text = String.Format("Do you wish to change the colour to {0}", colourName);
}
private void btnConfirm_Click(object sender, EventArgs e)
{
btnConfirm.DialogResult = DialogResult.OK;
}
private void btnCancel_Click(object sender, EventArgs e)
{
btnCancel.DialogResult = DialogResult.Cancel;
}
}
It works fine, but when the dialog pops up it requires me to click on a button twice to use it. Does anyone have an idea why?
You need to set this.DialogResult rather than btnxxx.DialogResult in the Click handlers, or set the btnxxx.DialogResult before the handlers.
The form's DialogResult is set to the button's before the Click method is run, so the first time the event is run the Form's DialogResult is left at None, but the second time it is set to the (now-set) button's DialogResult.

Categories