Error message to show which text boxes are blank C# - c#

Hey so I have all my code working and it's fine. But I'd like to clean it up a little.
At the moment I just have a message box show if there is an error in the input, so it would show "Please check your input", however I'd like it to show something like "Please check the following: firstname, secondname etc."
if ((FirstnameText.Text.Trim().Length == 0) || (SurnameText.Text.Trim().Length == 0)
|| (DateOfBirthText.Text.Trim().Length == 0) || (CourseText.Text.Trim().Length == 0)
|| (MatricNoText.Text.Trim().Length == 0) || (YearMarkText.Text.Trim().Length == 0)
|| (int.Parse(MatricNoText.Text) < 10000 || int.Parse(MatricNoText.Text) > 99999)
|| (int.Parse(YearMarkText.Text) < 0 || int.Parse(YearMarkText.Text) > 100))
{
errorMessage();
return;
}
public void errorMessage()
{
MessageBox.Show("Please check your input");
}
I know it's messy, but hey it works
Currently it just outputs that message, is there a simple way to output the specific textbox which has the error?
thanks

The built-in ErrorProvider component will work wonders for your situation. Drag it from the toolbox onto the designer for your form. It will appear at the bottom, where NotificationIcons and ContextMenuStrips appear. The great thing about the ErrorProvider is it give a visual feedback icon with a mouse over tooltip next to the control.
You can then use the "Validating" event of the control to check what you need:
private void FirstnameText_Validating (object sender, CancelEventArgs e)
{
string error = null;
if (FirstnameText.Text.Length == 0)
{
error = "You must enter a First Name";
e.Cancel = true; // This is important to keep focus in the box until the error is resolved.
}
ErrorProvider.SetError((Control)sender, error); // FirstnameText instead of sender to avoid unboxing the object if you care that much
}
You can also stick it in the Save button instead of raising it on the "Validating" event. To clean your code up even more, make a class that validates the input to keep non-UI stuff out of the UI.

Splitting up your code would be a start:
if ((FirstnameText.Text.Trim().Length == 0){
errorMessage("firstname is empty");
}
if (SurnameText.Text.Trim().Length == 0){
errorMessage("surname is empty");
}
Get the idea?

I often use Fluent Validation. The WithMessage method lets you specify an error message. The validator then returns you an enumerable of all error messages. There might also be a better fitting method for your specific problem.

If possible you re-write your code like below
Control errorControl =null;
foreach (Control ctrl in this.Controls)
{
if (ctrl is TextBox)
{
if (ctrl.Name == "MatricNoText")
{
if ((int.Parse(MatricNoText.Text) < 10000 || int.Parse(MatricNoText.Text) > 99999))
{
errorControl = ctrl;
}
}
else if (ctrl.Name == "MatricNoText")
{
if (int.Parse(YearMarkText.Text) < 0 || int.Parse(YearMarkText.Text) > 100)
{
errorControl = ctrl;
}
}
else
{
if (ctrl.Text.Length == 0)
{
errorControl = ctrl;
}
}
}
}
MessageBox.Show("Please check your input." + errorControl.Focus());

Related

How to evaluate multiple conditions at once, but detect which control failed and display error message?

I am currently working on a Winforms application which contains various ways of validating user input, all of which have to be met otherwise they are prompted with an ErrorProvider icon next to the control that failed. This is my saveForm function. This is also triggered from a Click event
My issue is that I need to check all of my conditions at the same time rather than one after another, as every time the press save they are the displayed with a new error until the validation is met.
I know I can obviously use the || operator or && but I need to appropriately display the corresponding message using the SetError method. So how would I be able to have the validation conditions evaluated at the same time but detect which control failed and display the unique message for that control.
SaveForm() method:
try
{
var errorProviders = new List<ErrorProvider>() { epEmail, epAlternative, epMobile, epTown, epLandline, epHouseName, epForeName, epSurname, epPostcode, epCountry, epHouseName, epLocality, epCounty };
if (string.IsNullOrWhiteSpace(txt_ForeName.Text) && string.IsNullOrWhiteSpace(txt_SurName.Text))
{
epBothNames.SetError(txt_SurName, "Error:");
epBothNames.SetError(txt_ForeName, "Error:");
return false;
}
if (cmb_Title.SelectedIndex == -1)
{
epTitle.SetError(cmb_Title, "Title");
return false;
}
if (cmb_PrefConTime.SelectedIndex == -1)
{
epPrefConTime.SetError(cmb_PrefConTime, "Error in: prefered contact time feild");
return false;
}
if (!isPhoneNumber())
{
epPrefConNumber.SetError(cmb_PrefConNumber, "Error");
return false;
}
foreach (Control c in panel1.Controls)
{
if(c is SpellBox || c is TextBox)
{
if (!errorProviders.Any(e => e.GetError(c).Length > 0))
{
return false;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString())+ "Error has occurred, Please cancel and try again!");
}
return true;
It is hard to tell from just this bit of code, but I think if you remove the return statements in the if statements, and return all of the messages at the end of the method, you can set your fields with errors and return the messages.

If statement skips the elements except the first one in the for loop. How can I get the right solution for the other elements?

for (int i = 0; i < dt.Rows.Count; i++)
{
if (textBox1.Text == dt.Rows[i]["FIRSTNAME"].ToString().ToLower() && textBox2.Text == dt.Rows[i]["LASTNAME"].ToString().ToLower())
{
Main ss = new Main(); // Main is the another form which is seen after the successful enterance.
ss.Show();
break;
}
else {
MessageBox.Show("UserName or Password is Wrong");
}
}
I want to create a Windows form application using C# and PL/SQL database. I have a data information which consists of the FÄ°RSTNAME and LASTNAME of the two persons. Because of the for loop, I get both of the success and the failure messages at the same time for the second person's information. When for loop cannot match the second person's information with the first person's information, it shows the failure message. Then it sees right information. So, it returns the true message to me.
How can I return the beginning of the if statement to get the all solutions until the end of the database? I put the else statement's codes out of the for loop. I got always the failure message because of the non-existing the if statement to Control the failure.
Shortly, what do I need to do?
Lot of conceptual errors. The else statements is not out of the loop!
You need a flag to check if you have found or not the person in the loop. Then check this flag out of the loop.
bool found = false;
for (int i = 0; i < dt.Rows.Count; i++)
{
if (textBox1.Text == dt.Rows[i]["FIRSTNAME"].ToString().ToLower() && textBox2.Text == dt.Rows[i]["LASTNAME"].ToString().ToLower())
{
found = true;
break;
}
}
if (found)
{
Main ss = new Main(); // Main is the another form which is seen after the successful enterance.
ss.Show();
}
else
{
MessageBox.Show("UserName or Password is Wrong");
}
You can change this to Linq:
if (dt.AsEnumerable().Any( // Check if there is any row meeting criteria
r => r.RowState != DataRowState.Deleted && // row should not be deleted
r.Field<string>("FIRSTNAME").Equals(textBox1.Text, StringComparison.CurrentCultureIgnoreCase) && // First name matches ignoring case
r.Field<string>("LASTNAME").Equals(textBox2.Text, StringComparison.CurrentCultureIgnoreCase))) // Last name matches ignoring case
{
Main ss = new Main(); // Main is the another form which is seen after the successful enterance.
ss.Show();
}
else
{
MessageBox.Show("UserName or Password is Wrong");
}

Document is not ready in DocumentReady event?

I am using Awesomium 1.7.0.5 in order to load a page, fill some textboxes and click a button. I am trying to fill a textbox using an example from this thread: http://answers.awesomium.com/questions/857/webcontrol-type-in-webbrowser.html
Here is my code (I am using WPF control):
private void WbAwsOnDocumentReady(object sender, UrlEventArgs urlEventArgs)
{
if (wbAws == null || !wbAws.IsLive)
return;
//Thread.Sleep(555);
dynamic document = (JSObject)wbAws.ExecuteJavascriptWithResult("document");
if (document == null)
return;
using (document)
{
dynamic textbox = document.getElementById("email");
if (textbox == null)
return;
using (textbox)
{
textbox.value = "gaaffa";
}
}
}
It works but only with Thread.Sleep for 0.1-0.5 sec. Otherwise document is empty (not null) and/or textbox is null.
What should I do? Why it is not ready in DocumentReadyEvent?
Here is how I solved it:
WbAws.LoadingFrameCompleted += OnLoadingFrameCompleted;
WbAws.Source = new Uri("http://google.com");
private void OnLoadingFrameCompleted(...)
{
if (webView == null || !webView.IsLive ||
webView.ParentView != null || !e.IsMainFrame)
return;
LoadingFrameCompleted -= OnLoadingFrameCompleted;
// do something
}
LoadingFrameCompleted instead of DocumentReady and because it fires not only when I need it but also on app startup I subscribe to it just before navigating and unsubscribe after it. Also checking that it IsMainFrame.
edit: but with this solution it sometimes throws exception that document is not ready. So I am also waiting for it using Thread.Sleep.
Very old question. but for someone like me, who is facing this problem-
use LoadingFrameCompleted event with WebControl.IsNavigating == false and e.IsMainFrame == true condition.
if these conditions are true in this event then page is finished loading and you are ready to get HTML content.

How do I validate text entry to include only numbers?

I want to obligate the person who is using my program to enter only numbers in the text label in c#. How can i do that?
example :
number of equations : (he should only enter a number)
This code to obligate him to enter a number between 2 and 10 but i need a code for letters
if (int.Parse(txt1.Text) < 2 || int.Parse(txt1.Text) > 10)
{
l6.ForeColor = System.Drawing.Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
}
put this (or a variation of this, according to what you want to let the user to enter) in the textbox keypress event, so basically you will manage key presses in this textbox..
Add System.Media library to use the beep if the user enters wrong key, or remove it from the code...
if ((e.KeyChar >= '0') && (e.KeyChar <= '9') && (txt1.Text.Length < 10))
{
}
else if (e.KeyChar == 0x08)
{
//BACKSPACE CHAR
}
else if (txt1.SelectionLength > 0)
{
//IF TEXT SELECTED -> LET IT OVERRIDE
}
else
{
e.Handled = true;
SystemSounds.Beep.Play();
}
if (txt1.Text.Trim().Length > 0)
{
// Parse the value only once as it can be quite performance expensive.
Int32 value = Int32.Parse(txt1.Text)
if ((value >= 2) && (value <= 10))
{
l6.ForeColor = Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
// Clear the text...
txt1.Text = "";
}
else
{
// Your code here...
}
}
But, IMHO, TryParse is even better as it can handle bad string formats in a better way:
if (txt1.Text.Trim().Length > 0)
{
Int32 value;
if (!Int32.TryParse(txt1.Text, out value))
{
l6.ForeColor = Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
// Clear the text...
txt1.Text = "";
}
else
{
// Your code here...
}
}
What GUI do you use?
Using Winforms there are two ways that come to mind:
I recommend: Use a numericUpDown Control instead of a textBox. This way the user can only enter numbers and has nice Up/Down arrows to change the value. Plus you get handling of cursor keys.
Implement an Validating event handler.
Checking the various methods to insert text in a textbox to avoid non number chars is not an easy task and more often than not it fails somewhere. For example what about text pasted from the clipboard?, what about Backspace, Delete, Left, Right arrows keys?.
In my opinion it is better to follow a different approach.
Use the Validating event and let the user type or paste whatever he wants. At the validation event do you checks and advise the user or add a special errorProvider to signal the error:
private void l6_Validating(object sender, CancelEventArgs e)
{
int isNumber = 0;
if (l6.Text.Trim().Length > 0)
{
if (!int.TryParse(l6.Text, out isNumber))
{
e.Cancel = true;
errorProvider1.SetError(l6, "Svp choisir un nombre entre 2 et 10 ...";);
}
else
{
errorProvider1.SetError(l6, "");
}
}
}
}

If condition's logic is not working

I have added one label in form that is not visible to user.Base on the text that label contain proceed further.
Here is my logic,but it fail.I wanted like this,if label contain "No match" or "Time out",should not proceed.
If((!label.Text.Contain("No match")) || label.Text.Contain("Time out"))
{
// proceed further code
}
else
{
// code
}
Here Label contain "No match",then it move to else part that is right.But when label contain "Time out",then it go inside the if loop.So I modified code like this
If((!label.Text.Contain("No match")) || (!label.Text.Contain("Time out")))
{
// proceed further code
}
else
{
// code
}
still not working.If label contain "Time out",still it go into if loop not else loop.Label contain only one text at a time either "No match" or "Time out" or any other text.
I suspect you want:
if(!(label.Text.Contains("No match") || label.Text.Contains("Time out")))
{
// proceed further code
}
else
{
// code
}
Note the bracketing. The inner part is
label.Text.Contains("No match") || label.Text.Contains("Time out")
and then that's inverted. I would probably pull that out into a separate variable:
bool timedOutOrNoMatch = label.Text.Contains("No match") ||
label.Text.Contains("Time out");
if (!timedOutOrNoMatch)
{
}
else
{
}
Alternatively, invert the sense of it:
if (label.Text.Contains("No match") || label.Text.Contains("Time out"))
{
// Do whatever was in your else block.
}
else
{
// Do whatever was in your first block.
}
If your response to the "bad" labels is something that lets you return or throw an exception, this can also reduce the amount of nesting:
if (label.Text.Contains("No match") || label.Text.Contains("Time out"))
{
output.Text = "Go away";
return;
}
// Now handle the success case
Try with following code:
if(!(label.Text.Contains("No match") || label.Text.Contains("Time out")))
{
// proceed further code
}
else
{
// code
}
If you want to get right with your modified code, use AND operator:
if(!label.Text.Contains("No match") && !label.Text.Contains("Time out"))
{
// proceed further code
}
else
{
// code
}
To write your code in more understood form , you should write it in a way that it is readable and more understandable. I prefer to write this statement like this
bool ProceedFurther()
{
//Don't proceed if No Match
if(!label.Text.Contains("No match")) return false;
//Don't proceed if Time out
if(!label.Text.Contains("Time out")) return false;
//Proceed otherwise
return true;
}
and call ProceedFurther method at desired location.
If you really want only that statement, following is the best (mostly people forget to change || to && after they change the condition to negative (using !).
if(!label.Text.Contains("No match") && !label.Text.Contains("Time out"))

Categories

Resources