Form close after button click with no this.close() call - c#

This is a simple question, but i donĀ“t know where is the problem. I have a form that have some code, when i click into "crear" button, in that button i call to the function "Comprobar" that cheks if the textboxs are empty, if "Comprobar" is false then i show a message.
The problem: After clicking the button "Crear" the form show the message (if all are empty) and then the form close.
Here is the code
public partial class FrmNuevaCita : MetroForm
{
DataTools mytool = new DataTools();
DataSet ds = new DataSet();
BindingSource bs = new BindingSource();
// string searchDate = "";
int codigoPaciente = -1;
FrmBuscarPaciente BuscarPaciente = new FrmBuscarPaciente();
public FrmNuevaCita()
{
InitializeComponent();
BuscarPaciente.SetCode += new EventHandler(YouCliked);
}
private void YouCliked(object sender, EventArgs e)
{
codigoPaciente = BuscarPaciente.GetCodigoPaciente;
//MessageBox.Show("Codigito es " + codigoPacienteActual.ToString());
txtPaciente.Text = codigoPaciente.ToString();
}
public DateTime SetDate
{
set { dtpFechaCita.Value = value; }
}
private void mbCancelar_Click(object sender, EventArgs e)
{
this.Close();
}
private void metroRadioButton_CheckedChanged(object sender, EventArgs e)
{
this.cmbHora.Items.Clear();
if (metroRadioButton1.Checked == true)
{
this.cmbHora.Items.AddRange(new object[]
{"8:00","8:30","9:00","9:30","10:00","10:30","11:00","11:30"});
}
else if (metroRadioButton2.Checked == true)
{
this.cmbHora.Items.AddRange(new object[] { "12:00", "12:30", "13:00", "13:30", "14:00", "14:30", "15:00", "15:30","16:00","16:30","17:00","17:30","18:00","18:30","19:00" });
}
}
private void mtBuscar_Click(object sender, EventArgs e)
{
BuscarPaciente.Show();
}
private void mbCrear_Click(object sender, EventArgs e)
{
if (Comprobar()==false)
MessageBox.Show("Por favor complete todos los campos");
}
private bool Comprobar()
{
bool result = false;
if (txtPaciente.Text.Trim().Length != 0 && txtObservaciones.Text.Trim().Length != 0 && cmbHora.Text.Trim().Length != 0)
result = true;
return result;
}
}

Make sure, that "Clear" button has DialogResult property set to DialogResult.None.
And that form's CancelButton property is not set to "Clear" button.

have you debug it step-by-step?
Possible Problems:
The "CancelButton"-Option of your form is set to the "mbCrear_Click"-Button.
There might be some missformed linking of the events in your Form's Designerfile.
"mbCancelar_Click"-Event & "mbCrear_Click"-Event refers to the same button
Best thing would be, to set a breakpoint to "mbCrear_Click" and debug it step by step then you see where your form is closed. ;)
Hope i could help

Related

How can I do data synchronization between two child form inside parent container winforms?

I have this situation I want to synchronize informations in my dataGridView when I insert it on my add form like you can see on this picture.
In my Insert form on insert button I call Add form to pop up like this
private void button1_Click(object sender, EventArgs e)
{
if (addForm==null)
{
addForm = new AddForm();
}
addForm.MdiParent = this.ParentForm;
addForm.FormClosed += AddForm_FormClosed;
addForm.Show();
}
private void AddForm_FormClosed(object sender, FormClosedEventArgs e)
{
addForm = null;
}
On Add form in Accept click I insert informations and call fillDataGrid() method from Insert form to do data sync but nothing is shown data is shown just when I close Insert form and call it again does someone has susggestion how can I do this this is the first time I work with MdiContainer ?
private void buttonAccept_Click(object sender, EventArgs e)
{
if (validation())
{
Proizvod product = new Proizvod();
product.NazivProizvoda = textBoxName.Text;
product.Opis = textBoxDescription.Text;
product.SerijskiBroj = textBoxNumber.Text;
product.ZemljaPorijekla = textBoxCountry.Text;
if (pDal.insertProduct(product)==0)
{
MessageBox.Show("Informations are successfully inserted","Message");
InsertForm inForm = new InsertForm();
inForm.fillDataGrid();
}
}
}
My fillDataGrid() method and Load event of InsertForm:
public void fillDataGrid()
{
dataGridViewProducts.DataSource = null;
dataGridViewProducts.AutoGenerateColumns = false;
dataGridViewProducts.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewProducts.ColumnCount = 3;
dataGridViewProducts.Columns[0].Name = "Product name";
dataGridViewProducts.Columns[0].DataPropertyName = "NazivProizvoda";
dataGridViewProducts.Columns[1].Name = "Country";
dataGridViewProducts.Columns[1].DataPropertyName = "ZemljaPorijekla";
dataGridViewProducts.Columns[2].Name = "Product number";
dataGridViewProducts.Columns[2].DataPropertyName = "SerijskiBroj";
dataGridViewProducts.DataSource = pDal.getAllProducts();
}
private void InsertForm_Load(object sender, EventArgs e)
{
fillDataGrid();
}
private void InsertForm_Shown(object sender, EventArgs e)
{
dataGridViewProducts.CurrentCell = null;
dataGridViewProducts.ClearSelection();
}
Currently in buttonAccept_Click code, you have created a new instance of the list form and called its FillGrid. This way you are manipulating another instance of the list form which is different from the instance which is open and you can see. You are filling a different form which you didn't show it.
Instead of creating a new instance, create a constructor for your second form which accepts a parameter of first form type. Then when you want to create a new instance of seccod form, pass the instance of the first form (this) to second Form. Then in your save button call the FillGrid method of the passed instance.
For more information about how to manipulate another form, read this post. It contains some useful options about:
Pass data to second Form when creating
Manipulate second Form after showing
Manipulate first Form from second Form
Here is some code which belong to the ListForm:
private void ShowAddForm_Click(object sender, EventArgs e)
{
if (addForm == null)
{
addForm = new AddForm(this);
addForm.MdiParent = this.ParentForm;
addForm.FormClosed += AddForm_FormClosed;
}
addForm.Show();
}
private void AddForm_FormClosed(object sender, FormClosedEventArgs e)
{
addForm = null;
}
And here is the code for AddForm
public class AddForm
{
MyListForm listForm;
public AddForm(MyListForm f)
{
InitializeComponent();
listForm = f;
}
private void SaveVutton_Click(object sender, EventArgs e)
{
//perform validation and save data
f.FillGrid();
}
}

How to close multiple dialogs in the right way?

I pasted the most important parts of my code below.
As you can see I'd like to work with multiple Forms. But this is how my Form behaves:
It opens Selector, when I press the second button it find the .ini file and opens ExplorerForm, but Selector IS STILL OPEN. Ofcourse I don't want that. I can't click the Selector, I just hear an error sound and the Explorer Window blinks. When I close the Explorer, both, the Explorer AND the Selector close.
But NOW the Path form opens...
When I press one of the other buttons in the Selector, it doesn't find the .INI file (that's right) and opens the Path form (and closes it in the right way).
I already used search and even implemented one of the answers there:
How I can close a 1st form without closing the full application?
My Program.cs:
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Selector());
Selector.cs:
private void button1_Click(object sender, EventArgs e)
{
Path pathForm = new Path(0);
this.Hide();
pathForm.ShowDialog();
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
Path pathForm = new Path(1);
this.Hide();
pathForm.ShowDialog();
this.Close();
}
private void button3_Click(object sender, EventArgs e)
{
Path pathForm = new Path(2);
this.Hide();
pathForm.ShowDialog();
this.Close();
}
Path.cs:
public Path(int currGame)
{
intGame = currGame;
if(MyIni.KeyExists("Path"+intGame))
{
var GamePath = MyIni.Read("Path"+intGame);
if(Directory.Exists(GamePath))
{
if (Directory.GetFiles(
GamePath, gameEXE(intGame), SearchOption.TopDirectoryOnly).Count() > 0)
{
InitializeComponent();
Explorer explorerForm = new Explorer();
this.Hide();
explorerForm.ShowDialog();
this.Hide();
}
}
}
InitializeComponent();
label1.Text = label1.Text + " " + gameString(currGame) + "!";
RegistryKey rk = Registry.LocalMachine;
RegistryKey sk1 = rk.OpenSubKey(
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 12100");
// III Steam
RegistryKey sk2 = rk.OpenSubKey(
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 12110");
// Vice City Steam
RegistryKey sk3 = rk.OpenSubKey(
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 12120");
// San Andreas Steam
if(intGame == 0)
{
if (sk1 != null)
{
if (sk1.GetValueNames().Contains("InstallLocation")
&& sk1.GetValue("InstallLocation").ToString() != "")
{
textBox1.Text = sk1.GetValue("InstallLocation").ToString();
}
}
}
else if(intGame == 1)
{
if(sk2 != null)
{
if(sk2.GetValueNames().Contains("InstallLocation")
&& sk2.GetValue("InstallLocation").ToString() != "")
{
textBox1.Text = sk2.GetValue("InstallLocation").ToString();
}
}
}
else if (intGame == 2)
{
if (sk3 != null)
{
if (sk3.GetValueNames().Contains("InstallLocation")
&& sk3.GetValue("InstallLocation").ToString() != "")
{
textBox1.Text = sk3.GetValue("InstallLocation").ToString();
}
}
}
}
Try modify involved code of your Selector.cs in this way:
private void button1_Click(object sender, EventArgs e)
{
this.StartPathForm(1);
}
private void button2_Click(object sender, EventArgs e)
{
this.StartPathForm(2);
}
private void button3_Click(object sender, EventArgs e)
{
this.StartPathForm(3);
}
private void StartPathThread(int currGame)
{
System.Threading.Thread pathThread = new System.Threading.Thread(PathThreadStart);
pathThread.SetApartmentState(System.Threading.ApartmentState.STA);
pathThread.Start(currGame);
this.Close();
}
private void PathThreadStart(object currGame) {
Application.Run(new Path((int) currGame));
}
With this modification, a new thread would be initialized and the Path form will run on it. Then, the Selector form would close immediately. Hope this fit your use.

How do I set a toolstriptextbox accept button to call a function which a toolstripbutton calls?

I have a TextBox in my winforms. When a user starts typing in it I will like to set the AcceptButton property to call another function. However it is calling another function which is called by a Button in my ToolStrip. To elaborate, here is my code below:
private void locNameTxtBx_TextChanged(object sender, EventArgs e)
{
this.AcceptButton = searchBtn;
}
private void searchBtn_Click_1(object sender, EventArgs e)
{
if (locNameTxtBx.Text != "")
{
List<SearchLocation> locationsArray = new List<SearchLocation>();
var location = locNameTxtBx.Text;
SearchLocation loc = new SearchLocation();
loc.Where = location;
locationsArray.Add(loc);
mapArea.VE_FindLocations(locationsArray, true, true, null);
mapArea.VE_SetZoomLevel(14);
}
else
{
MessageBox.Show("Please Enter Location");
}
}
searchBtn is a Button in the ToolStrip. So, when I try to run this code, I get this error
Cannot implicitly convert type 'System.Windows.Forms.ToolStripButton' to 'System.Windows.Forms.IButtonControl'. An explicit conversion exists (are you missing a cast?)
I have tried casting it as a ToolstripButton like this:
private void locNameTxtBx_TextChanged(object sender, EventArgs e)
{
this.AcceptButton = (ToolStripButton)searchBtn;
}
You could use two delegates and set the delegate to use in the locNameTxtBx_TextChanged method.
private delegate void ToUseDelegate();
ToUseDelegate delegateIfNoText = delegate{
MessageBox.Show("Please Enter Location");
}
ToUseDelegate delegateIfText = delegate{
List<SearchLocation> locationsArray = new List<SearchLocation>();
var location = locNameTxtBx.Text;
SearchLocation loc = new SearchLocation();
loc.Where = location;
locationsArray.Add(loc);
mapArea.VE_FindLocations(locationsArray, true, true, null);
mapArea.VE_SetZoomLevel(14);
}
ToUseDelegate delToUse = delegateIfNoText;
private void locNameTxtBx_TextChanged(object sender, EventArgs e)
{
this.AcceptButton = searchBtn;
if (locNameTxtBx.Text != ""){
delegateToUse = delegateIfNoText;
} else {
delegateToUse = delegateIfText;
}
}
private void searchBtn_Click_1(object sender, EventArgs e)
{
delegateToUse();
}

how to call MdiChild from MDIParent form

I create a new MdiChild from MainForm using this method:
AdminLogInForm adminForm;
private void LogInAsAdminMenuItem_Click(object sender, EventArgs e)
{
if (adminForm == null)
{
adminForm = new AdminLogInForm();
adminForm.MdiParent = this;
adminForm.Show();
adminForm.Dock = DockStyle.Fill;
adminForm.BringToFront();
LogInAsAdminMenuItem.Enabled = false;
}
else
{
adminForm.Activate();
adminForm.BringToFront();
}
}
Why when i close my child, using in chld form "this.close()" using that method i cant open it anymore?
there i call close();
private void cancelLogInButton_Click(object sender, EventArgs e)
{
this.MdiParent.Activate();
if(this.MdiParent!=null)
((MainForm)this.MdiParent).LogInAsAdminMenuItem.Enabled = true;
this.Close();
}
by the way to make work that I asked before I hed to plase this.Close(); after all statements .
By closing the form you are not making adminForm instance to null (Which is what your if condition will check when you try to open it next time.)
On diposal of your form make adminForm = null and then your if condition will work next time.
private void LogInAsAdminMenuItem_Click(object sender, EventArgs e)
{
if (adminForm == null)
{
adminForm = new AdminLogInForm(this);
adminForm.Disposed += new EventHandler(adminForm_Disposed); //Add Disposed EventHandler
adminForm.MdiParent = this;
adminForm.Show();
adminForm.Dock = DockStyle.Fill;
adminForm.BringToFront();
LogInAsAdminMenuItem.Enabled = false;
}
else
{
adminForm.Activate();
adminForm.BringToFront();
}
}
void adminForm_Disposed(object sender, EventArgs e)
{
adminForm = null;
}
As Described by Marshal that the closing of a form makes it disposed you should add a condition for disposing as well like this
AdminLogInForm adminForm;
private void LogInAsAdminMenuItem_Click(object sender, EventArgs e)
{
if (adminForm == null || adminForm.IsDisposed)
{
adminForm = new AdminLogInForm();
adminForm.MdiParent = this;
adminForm.Show();
adminForm.Dock = DockStyle.Fill;
adminForm.BringToFront();
LogInAsAdminMenuItem.Enabled = false;
}
else
{
adminForm.Activate();
adminForm.BringToFront();
}
}
Or you can also create a function to use a form as mdi
like this

How to check in real time if data was enteder from one of the classes into a texbox?

My question comes from a problem which I have right now. I have MainWindow, AuthenticateWindow, and AddEntryWindow which all are WinForms. In main window I have possibility to Authenticate and Add Entry into my main windows textbox. They can not add an entry until they authenticate (no problem with this). I need to add an entry to the text box which will update my main windows textbox. The problem if, how can I check if entry was added to my textbox?
I am trying to have a Save option from menu strip. I am getting an error whenever I am trying to save an empty file. How could I authenticate the saving process by Save button by having it first disabled, and enabled after entry was added?
I could always verify if if textbox had an entry but I want to have button disabled first, and enabled after entry was added. I do not have a privilege to do so as of right now.
Please ask questions if I am not clear enough.
private void tsmiSave_Click(object sender, EventArgs e)
{
// Open sfdSaveToLocation which let us choose the
// location where we want to save the file.
if (txtDisplay.Text != string.Empty)
{
sfdSaveToLocation.ShowDialog();
}
}
MainWindow.cs
using System;
using System.IO;
using System.Windows.Forms;
namespace Store_Passwords_and_Serial_Codes
{
public partial class MainWindow : Form
{
private AuthenticateUser storedAuth;
public MainWindow()
{
InitializeComponent();
}
private void MainWindow_Load(object sender, EventArgs e)
{
// Prohibit editing.
txtDisplay.Enabled = false;
}
public string ChangeTextBox
{
get
{
return this.txtDisplay.Text;
}
set
{
this.txtDisplay.Text = value;
}
}
private void tsmiAuthenticate_Click(object sender, EventArgs e)
{
AuthenticationWindow authWindow = new AuthenticationWindow();
authWindow.ShowDialog();
storedAuth = authWindow.Result;
}
private void tsmiAddEntry_Click(object sender, EventArgs e)
{
if (storedAuth == null)
{
DialogResult result = MessageBox.Show
("You must log in before you add an entry."
+ Environment.NewLine + "You want to authenticate?",
"Information", MessageBoxButtons.YesNo,
MessageBoxIcon.Information);
if (result == DialogResult.Yes)
{
AuthenticationWindow authWindow =
new AuthenticationWindow();
authWindow.ShowDialog();
storedAuth = authWindow.Result;
AddEntryWindow addWindow = new AddEntryWindow
(this, storedAuth.UserName, storedAuth.Password);
addWindow.ShowDialog();
}
}
else
{
AddEntryWindow addWindow = new AddEntryWindow
(this, storedAuth.UserName, storedAuth.Password);
addWindow.ShowDialog();
}
}
private void tsmiClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void tsmiSave_Click(object sender, EventArgs e)
{
// Open sfdSaveToLocation which let us choose the
// location where we want to save the file.
sfdSaveToLocation.ShowDialog();
}
private void sfdSaveToLocation_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
{
string theFileName = sfdSaveToLocation.FileName;
EncryptDecrypt en = new EncryptDecrypt();
string encrypted = en.Encrypt(txtDisplay.Text,
storedAuth.UserName, storedAuth.Password);
MessageBox.Show(encrypted);
File.WriteAllText(theFileName, encrypted);
}
}
}
AddEntryWindow.cs
using System;
using System.Windows.Forms;
// Needed to be used with StringBuilder
using System.Text;
// Needed to be used with ArrayList.
using System.Collections;
namespace Store_Passwords_and_Serial_Codes
{
public partial class AddEntryWindow : Form
{
string user, pass;
// Initializind ArrayList to store all data needed to be added or retrived.
private ArrayList addedEntry = new ArrayList();
// Initializing MainWindow form.
MainWindow mainWindow;
// Default constructor to initialize the form.
public AddEntryWindow()
{
InitializeComponent();
}
public AddEntryWindow(MainWindow viaParameter, string user, string pass)
: this()
{
mainWindow = viaParameter;
this.user = user;
this.pass = pass;
}
private void AddEntryWindow_Load(object sender, EventArgs e)
{ }
private void btnAddEntry_Click(object sender, EventArgs e)
{
// Making sure that type is selected.
if (cmbType.SelectedIndex == -1)
{
MessageBox.Show("Please select entry type!", "Error!",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// Each field must be filled for specified type.
// Here we are checking if all fields were filled.
else if ((cmbType.SelectedIndex == 0 && (txtUserName.Text == string.Empty || txtPassword.Text == string.Empty)) ||
(cmbType.SelectedIndex == 1 && (txtURL.Text == string.Empty || txtPassword.Text == string.Empty)) ||
(cmbType.SelectedIndex == 2 && (txtSoftwareName.Text == string.Empty || txtSerialCode.Text == string.Empty)))
{
MessageBox.Show("Please fill all the fields!", "Error!",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
int totalEntries = 0;
if(cmbType.SelectedIndex == 0)
addedEntry.Add(new AddPC(cmbType.Text,
txtUserName.Text, txtPassword.Text));
else if(cmbType.SelectedIndex == 1)
addedEntry.Add(new AddWebSite(cmbType.Text,
txtUserName.Text, txtPassword.Text, txtURL.Text));
else if(cmbType.SelectedIndex == 2)
addedEntry.Add(new AddSerialCode(cmbType.Text,
txtSoftwareName.Text, txtSerialCode.Text));
StringBuilder stringBuilder = new StringBuilder();
foreach (var list in addedEntry)
{
if (list is AddPC)
{
totalEntries++;
AddPC tmp = (AddPC)list;
stringBuilder.Append(tmp.ToString());
}
else if (list is AddWebSite)
{
totalEntries++;
AddWebSite tmp = (AddWebSite)list;
stringBuilder.Append(tmp.ToString());
}
else if (list is AddSerialCode)
{
totalEntries++;
AddSerialCode tmp = (AddSerialCode)list;
stringBuilder.Append(tmp.ToString());
}
}
mainWindow.ChangeTextBox = stringBuilder.ToString();
mainWindow.tsslStatus.Text = "A total of " + totalEntries + " entries added.";
// Clearing all fields.
ClearFields();
}
}
private void btnClear_Click(object sender, EventArgs e)
{
ClearFields();
}
private void btnClose_Click(object sender, EventArgs e)
{
// Closing the Add Entry Window form.
this.Close();
}
private void cmbType_SelectedIndexChanged(object sender, EventArgs e)
{
// Deciding which data must be entered depending on
// what type is selected from combo box.
// PC
if (cmbType.SelectedIndex == 0)
{}
// Web Site
else if (cmbType.SelectedIndex == 1)
{}
// Serial Code
else if (cmbType.SelectedIndex == 2)
{}
}
private void ClearFields()
{
// Clearing all fields to the default state.
}
}
}
Regards.
It sounds like you probably just want to subscribe to the TextChanged event, which will be fired whenever the text in the textbox changes.
I can't say I really followed everything that you're doing, but I think you should be fine to just enable or disable your Save button within that event handler.
EDIT: It's not really clear where all your different components live, but you want something like:
// Put this after the InitializeComponent() call in the constructor.
txtDisplay.TextChanged += HandleTextBoxTextChanged;
...
private void HandleTextBoxTextChanged(object sender, EventArgs e)
{
bool gotText = txtDisplay.Text.Length > 0;
menuSaveButton.Enabled = gotText;
}
I'd also strongly advise you not to use ArrayList but to use the generic List<T> type. The non-generic collections should almost never be used in new code.

Categories