C# - Highlight wrong controls when validating - c#

I am trying to validate windows form with try catch and so far I succeeded. My goal is when someone forgot to fill the gap or put in incorrect entry, catch returns messagebox with a warning. Now I also have Validating event on every control I want to validate so when somebody leave it empty or in incorrect format it will show the error next to the control. That seems ok so far (for me, at least) but my issue is, that if user doesn't even click to one box it only shows message box, but it won't highlight wrong controls.
Below is my code:
private void createButton_Click(object sender, EventArgs e)
{
try
{
Book newBook = new Book(titleBox.Text, authBox.Text, Convert.ToInt32(yearBox.Text), Convert.ToInt32(editBox.Text), pubComboBox.Text, descBox.Text);
bookList.Add(newBook);
booklistListBox.DataSource = bookList;
}
catch (FormatException)
{
MessageBox.Show("You probably missed a gap or put in incorrect form");
}
}
and those validating events:
private void titleBox_Validating(object sender, CancelEventArgs e)
{
if (titleBox.Text.Trim() == String.Empty)
{
errorProvider.SetError(titleBox, "Title is required");
e.Cancel = true;
}
else
{
errorProvider.SetError(titleBox, "");
}
}
private void authBox_Validating(object sender, CancelEventArgs e)
{
if (authBox.Text.Trim() == String.Empty)
{
errorProvider.SetError(authBox, "Author is required");
e.Cancel = true;
}
else
{
errorProvider.SetError(authBox, "");
}
}
private void yearBox_Validating(object sender, CancelEventArgs e)
{
if (yearBox.Text.Trim() == String.Empty)
{
errorProvider.SetError(yearBox, "Year is required");
e.Cancel = true;
}
else
{
errorProvider.SetError(yearBox, "");
}
}
private void editBox_Validating(object sender, CancelEventArgs e)
{
if (editBox.Text.Trim() == String.Empty)
{
errorProvider.SetError(editBox, "Edition is required");
e.Cancel = true;
}
else
{
errorProvider.SetError(editBox, "");
}
}
private void pubComboBox_Validating(object sender, CancelEventArgs e)
{
if (pubComboBox.Text.Trim() == String.Empty)
{
errorProvider.SetError(pubComboBox, "Publisher is required");
e.Cancel = true;
}
else
{
errorProvider.SetError(pubComboBox, "");
}
}
private void descBox_Validating(object sender, CancelEventArgs e)
{
if (descBox.Text.Trim() == String.Empty)
{
errorProvider.SetError(descBox, "Description is required");
e.Cancel = true;
}
else
{
errorProvider.SetError(descBox, "");
}
}
So is there way to, I don't know, change focus or something like that, forced with pressing the create button?
Thank You

Try using ValidateChildren():
private void createButton_Click(object sender, EventArgs e)
{
bool gotIssues = this.ValidateChildren();
if (gotIssues)
{
// someone didn't validate well...
}
}

So, the issue here is that you want to have it highlight in either of two scenarios:
1) When you leave the field and its contents are invalid (empty in this case)
2) When you click the create button and the field in question has invalid contents
And so I would create a single textBox_checkIfEmpty(object sender, EventArgs e) method:
private void textBox_checkIfEmpty(object sender, EventArgs e)
{
var asTb = sender as TextBox;
if (asTb != null && asTb.Text.Trim() == String.Empty)
{
errorProvider.SetError(asTb, "I'll leave it to you to abstract the error message appropriately");
e.Cancel = true;
}
else
{
errorProvider.SetError(asTb, "");
}
}
Then, you can set this method as the handler for your Validate event on your desired required controls, and you can also call the same method from the create button's handler, looping through the required TextBox instances and executing the method on each.
UPDATE
J. Hudler's ValidateChildren solution would be a more (developer) efficient tail to mine, as opposed to looping through the desired controls. That said, if the form has many children, and you only need to validate several, it might be helpful to loop still. Just depends on your specific scenario. My only other question is whether or not ValidateChildren is infinitely recursive, or if it only goes one level down (immediate children rather than all descendants).

the event validating for control call when the mouse click on the control and then leave it from the control. In your case when the user does not click on the control it will not trigger the validating event. U can do this by making your own function and call them on creat event.
private void button1_Click(object sender, EventArgs e)
{
textBox1_Validating(sender);
}
public void textBox1_Validating(object sender)
{
MessageBox.Show("validating");
errorProvider1.SetError(textBox1, "provide");
}

Related

Handle all checkbox events on a single method

I found some similar questions but none of them on C# Winforms. I have many similar methods for different Checkboxes I have on my form, but now the number of checks is about to double and I'm looking for a simpler way of doing this.
Here's an example:
private void CheckPET_Click(object sender, EventArgs e)
{
if (CheckPET.Checked)
{
CheckAdicionarMaterial("PET");
}
else
{
if (Confirmacao())
CheckRemoverMaterial("PET");
else
CheckPET.Checked = true;
}
}
I have one of these for each Checkbox, and all of them follow the same pattern, so if I could have a method that handles all clicks I could do something like this:
private void GenericCheckbox_Click(object sender, EventArgs e)
{
if (Checkbox.Checked)
{
CheckAdicionarMaterial(Checkbox.Text);//The text of the boxes is always the string I want to pass here.
}
else
{
if (Confirmacao())
CheckRemoverMaterial(Checkbox.Text);
else
Checkbox.Checked = true;
}
}
What can I do to achieve this?
If I understand the question correctly - binding a single function as an event handler for several checkboxes?
private void checkBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox checkbox = sender as CheckBox;
if (checkbox == null) return;
if (checkbox.Checked)
{
CheckAdicionarMaterial(checkbox.Text);//The text of the boxes is always the string I want to pass here.
}else
{
if (Confirmacao("Desmarcar removerá todas ocorrências do material. Continuar?"))
CheckRemoverMaterial(checkbox.Text);
else
checkbox.Checked = true;
}
}

How to validate textboxes before saving

I got this code and what I am looking for is to validate the text boxes before saving. Now if I fill the textboxes then I clear any of them it saves anyway. How could I possibly check if the are all filled before saving? I was trying to add handlers for textchanged events but I didn't work. Any suggestion will be appreciated, cheers.
public partial class frmTrainer : Form
{
public frmTrainer()
{
InitializeComponent();
// We initialize new event handlers for the subjects textboxes
this.englishTextBox.KeyPress += new KeyPressEventHandler(englishTextBox_KeyPress);
this.mathsTextBox.KeyPress += new KeyPressEventHandler(mathsTextBox_KeyPress);
this.physicsTextBox.KeyPress += new KeyPressEventHandler(physicsTextBox_KeyPress);
}
// We create a public list for all the textbox controls in the form
public List textBoxes = new List();
private void frmTrainer_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'rCMDataSet.Students_Credentials' table. You can move, or remove it, as needed.
this.students_CredentialsTableAdapter.Fill(this.rCMDataSet.Students_Credentials);
// We initialize the List of textboxes
textBoxAdd();
}
// We create method stubs for the KeyPress event on the subjects textboxes
// to allow them receive only numeric inputs
private void englishTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
MessageBox.Show("Numeric input accepted only");
}
}
private void mathsTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
MessageBox.Show("Numeric input accepted only");
}
}
private void physicsTextBox_KeyPress(object sendet, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
MessageBox.Show("Numeric input accepted only");
}
}
// We create a method to add each textbox to the List
private void textBoxAdd()
{
textBoxes.Add(studentIDTextBox);
textBoxes.Add(first_NameTextBox);
textBoxes.Add(last_NameTextBox);
textBoxes.Add(usernameTextBox);
textBoxes.Add(passwordTextBox);
textBoxes.Add(englishTextBox);
textBoxes.Add(mathsTextBox);
textBoxes.Add(physicsTextBox);
textBoxes.Add(trainerIDTextBox);
}
// We create a private method to validate the textboxes
private void CheckTextBox()
{
foreach(TextBox txt in textBoxes)
{
if (string.IsNullOrWhiteSpace(txt.Text))
{
MessageBox.Show("Please insert data correctly");
}
}
}
private void students_CredentialsBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.CheckTextBox();
try
{
//this.Validate();
this.students_CredentialsBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.rCMDataSet);
MessageBox.Show("Data saved successfully");
}
catch(System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void toolStripExit_Click(object sender, EventArgs e)
{
// We disable the automatic validation when clicking Exit button
this.AutoValidate = AutoValidate.Disable;
// We call the method to close the application
Application.Exit();
}
private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e)
{
// We disable the navigation buttons to prevent any skipping errors
this.bindingNavigatorMoveFirstItem.Enabled = false;
this.bindingNavigatorMoveLastItem.Enabled = false;
this.bindingNavigatorMoveNextItem.Enabled = false;
this.bindingNavigatorMovePreviousItem.Enabled = false;
}
}
}
In your students_CredentialsBindingNavigatorSaveItem_Click event, while you do call the CheckTextBox method to "validate" your controls, you're essentially not doing anything about empty controls except to show a MessageBox. What you should do is to return a boolean on the validation method whenever an empty input is found:
private bool CheckTextBox()
{
bool isValid = true;
foreach(TextBox txt in textBoxes)
{
if (string.IsNullOrWhiteSpace(txt.Text))
{
isValid = false;
MessageBox.Show("Please insert data correctly");
break; //You only need one invalid input to prevent saving
}
}
return isValid;
}
And in your Click event, check for the return value of the method and exit the event if an invalid input is detected:
private void students_CredentialsBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
if(!this.CheckTextBox()) return; //Stop executing code if there's invalid input
try
{
//this.Validate();
this.students_CredentialsBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.rCMDataSet);
MessageBox.Show("Data saved successfully");
}
catch(System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Did you try using the String.Trim method on your text box text like:
foreach(TextBox txt in textBoxes)
{
//trim whitespaces from text at both ends and might be better to operate on a string
String text = txt.ToString();
text.Trim();
if (string.IsNullOrWhiteSpace(text))
{
MessageBox.Show("Please insert data correctly");
}
}

Controling if condition in text change function

I want if a user type the character "a" in textbox, message box with message "Ok" displays, and then textbox should clear.But I am facing the problem that when I type "a" message "Ok" is displays and along with message "No" is also displays.But when I remove the statment of clear then all goes good. Please tell me how to overcome this problem ?
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text == "a")
{
textBox1.Text = "";
MessageBox.Show("Ok");
}
else
{
MessageBox.Show("No");
}
}
It's because the Text="" triggered the TextChanged one more time. Use some flag like this:
bool suppressTextChanged;
private void textBox1_TextChanged(object sender, EventArgs e) {
if(suppressTextChanged) return;
if (textBox1.Text == "a") {
suppressTextChanged = true;
textBox1.Text = "";
suppressTextChanged = false;
MessageBox.Show("Ok");
} else {
MessageBox.Show("No");
}
}
NOTE: The code above supposes you want to check against a string ("a" is just an example). If you want to check against a character. Use the KeyPress event instead.
You're using the TextChanged event of the textbox. When you change the text manually the TextChanged event runs again and this time the else expression runs.
private void textBox1_TextChanged(object sender, EventArgs e)
{
if(textBox1.Text != "")
if (textBox1.Text == "a")
{
textBox1.Text = "";
MessageBox.Show("Ok");
}
else
{
MessageBox.Show("No");
}
}
That is because when you set textBox1.Text = ""; the event textBox1_TextChanged is raised one more and there is not a letter 'a' in the textbox and therefore a messasge box with "No" is also displayed.
You need to check if the change in textBox1.Text was from the user, or from you. "No" is displayed because you change the text to something ("") that is not "a". You could keep a boolean flag that indicates whether you want to react on the change:
bool changedByCode = false;
private void textBox1_TextChanged(object sender, EventArgs e)
{
if(changedByCode) return;
if (textBox1.Text == "a")
{
changedByCode = true;
textBox1.Text = "";
changedByCode = false;
MessageBox.Show("Ok");
}
else
{
MessageBox.Show("No");
}
}
You should handle KeyUp event
public Form1()
{
InitializeComponent();
textBox1.KeyUp+=new KeyEventHandler(textBox1_KeyUp);
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (textBox1.Text == "a")
{
textBox1.Text = "";
MessageBox.Show("Ok");
}
else
{
MessageBox.Show("No");
}
}
That's because the textBox1.Text = "" calls textBox1_TextChanged again.

If statements involving Radiobuttons

I'm currently creating a calculator type form on C#. I have four radiobuttons (Addition, subtraction, multi, and div) and a label in between two textboxes. The label changes according to the selected radiobutton, (for example if I selected the Addition radiobutton the label would read "+"). The problem I'm experiencing with this code:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked == true)
{
label3.Text = ("+");
}
else if (radioButton2.Checked == true)
{
label3.Text = ("-");
}
else if (radioButton3.Checked == true)
{
label3.Text = ("x");
}
else if (radioButton4.Checked == true)
{
label3.Text = ("/");
}
}
is when I select the division button the label does not change unless I go through all the buttons and THEN other radio buttons (such as subtraction), when selected, do not change the label until multiple tries. I tried changing the last line to an "else label3.text=("/");" but it doesn't really change anything other than the order of errors.
Any help would be appreciated! Thanks :)
I think you need to check if the radio button is checked in each individual radioButtonX_CheckedChanged method like so:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked)
{
label3.Text = ("+");
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
if (radioButton2.Checked)
{
label3.Text = ("-");
}
}
private void radioButton3_CheckedChanged(object sender, EventArgs e)
{
if (radioButton3.Checked)
{
label3.Text = ("x");
}
}
private void radioButton4_CheckedChanged(object sender, EventArgs e)
{
if (radioButton4.Checked)
{
label3.Text = ("/");
}
}
Let me know if that helps, and if you are still having the issue.
You may want to change how you check for the Checked button. MrB's solution works, but if you'd like to keep your selection code in a single block (as you have), make sure all your radio buttons have their CheckedChanged event subscribed to something similar to the following:
private void RadioButtonCheckedChanged(object sender, EventArgs e)
{
var radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
switch (radioButton.Text)
{
case "Add":
label3.Text = "+";
break;
case "Subtract":
label3.Text = "-";
break;
case "Divison":
label3.Text = "/";
break;
}
}
}
You can also switch on another property, such as the RadioButton.Tag field, whatever may be meaningful to you.
As far as the actual reason your code is failing, it's hard to understand without ensuring which RadioButton's have their events set properly, and seeing the incorrect results.
protected void Page_Load(object sender, EventArgs e)
{
agm.Visible = RadioButtonList1.SelectedValue == "1" ? true : false;
}

Form Closes When it Shouldn't

I have two Forms in my application. They way I call Form 2 is like this:
Form 1:
private void btnTest_Click(object sender, EventArgs e)
{
DialogResult result = new System.Windows.Forms.DialogResult();
Add_Link addLink = new Add_Link();
result=addLink.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
//
}
}
Form 2:
private void btnAdd_Click(object sender, EventArgs e)
{
if(validURL(txtSubLink.Text))
{
HyperLink add = new HyperLink(txtSubLink.Text,txtSubText.Text,"URL");
this.build = add;
}
else
{
MessageBox.Show("Valid URL Needed! " + txtSubLink.Text, "ERROR");
}
}
My problem is if the user clicks the Add button, the error message shows(because the data is invalid or the textboxes are empty) BUT it closes the form. I only want the user to close the form and pass the data back if the two textboxes contain the proper data. If the two textboxes don't contain the proper data OR is empty, when the user clicks Add, the error message should show, and the Form 2 should remain open, How do I get that to happen...?
I suspect your btnAdd has its DialogResult property set to OK. Unset that, and then add this.DialogResult = DialogResult.OK in your event handler when you're satisfied with the input.
private void btnAdd_Click(object sender, EventArgs e)
{
if(validURL(txtSubLink.Text))
{
HyperLink add = new HyperLink(txtSubLink.Text,txtSubText.Text,"URL");
this.build = add;
this.DialogResult = DialogResult.OK;
}
else
{
MessageBox.Show("Valid URL Needed! " + txtSubLink.Text, "ERROR");
}
}

Categories

Resources