In winforms there are different controls like textbox,combobox dropdown. In these some fields are mandatory and some are not, so while validating all fields, if there is some error then it shows error and returns to that that method again, and all the control value gets clear. I want to keep those control value in form as such if error comes. How do I do this? Maybe I can check all control values not null, or something like this, but for not mandatory can't check this. How do I do it? Here is the code. I am displaying errors like this.
private void button1_Click(object sender, EventArgs e)
{
string title = txtTitle.Text;
string fname = txtFirstName.Text;
string mname = txtMiddleName.Text;
string lname = txtLastName.Text;
int feeAmount;
if (txtTitle.Text.Equals(""))
{
MessageBox.Show("Please Enter Title");
return;
}
if (txtFirstName.Text.Equals(""))
{
MessageBox.Show("Please Enter First Name");
return;
}
if (fname.Length < 3)
{
MessageBox.Show("Firstname must contain atleast 3 Character");
return;
}
if (txtLastName.Text.Equals(""))
{
MessageBox.Show("Please Enter Last Name");
return;
}
if (rdoPercent.Checked == false && rdoPerPatnt.Checked == false)
{
MessageBox.Show("Please Select Fee Unit");
return;
}
if(db.NewDrMaster(title,fname,mname,lname,txtRegistrationNo.Text,txtSpeciality.Text, txtContact1.Text,landlineno,cmbCity.SelectedItem.ToString(),Address,txtPincode.Text,txtEmailID.Text,feeUnit,txtFee.Text,DrType,Display))
{
MessageBox.Show("Doctor Refernced By added Successfully");
}
else
{
MessageBox.Show("failed");
}
}
Related
I have tried to make a simple C# Windows Forms Application .NET Framework, where I have a class(string Name, string LastName, string Classroom, string DateDay) with three textbox entries and one date time picker entry. All of these entries get saved into a list and a list box. I need to add onto my if statement to check with for each, if the entry I am trying to put into the list/list box is already in the list box. If the entry is duplicate it will give a message box error, if it is not duplicate it will add it using the continuation of the if statement.
Here's my attempt at the duplication check:
private void btnAdding_Click(object sender, EventArgs e)
{
if (txtName.Text != "" && txtLastName.Text != "" && txtClassroom.Text != "" )
{
if (ListBox.Items.Cast<string>().Contains(ListBox.Items.ToString()))
{
MessageBox.Show("This entry already exists.", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else {
List.Add(new Student(txtName.Text, txtLastName.Text, txtClassroom.Text, dateDay.Value.ToString("dd.MM.yyyy")));
RefreshCheck();
}
}
else
{
MessageBox.Show("You didnt fill out all the text boxes.", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void RefreshCheck()
{
ListBox.Items.Clear();
for (int i = 0; i < seznam.Count(); i++)
{
ListBox.Items.Add(List[i].StudentAdd());
this.txtName.Clear();
this.txtLastName.Clear();
this.txtClassroom.Clear();
this.dateDay.Value = DateTime.Today;
this.tabStudent.SelectedTab = this.tabCheck;
}
}
Here's my original code without the duplication check (just the if statement):
private void btnAdding_Click(object sender, EventArgs e)
{
if (txtName.Text != "" && txtLastName.Text != "" && txtClassroom.Text != "" )
{
List.Add(new Student(txtName.Text, txtLastName.Text, txtClassroom.Text, dateDay.Value.ToString("dd.MM.yyyy")));
RefreshCheck();
}
else
{
MessageBox.Show("You didnt fill out all the text boxes.", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void RefreshCheck()
{
ListBox.Items.Clear();
for (int i = 0; i < List.Count(); i++)
{
ListBox.Items.Add(List[i].StudentAdd());
this.txtName.Clear();
this.txtLastName.Clear();
this.txtClassroom.Clear();
this.dateDay.Value = DateTime.Today;
this.tabStudent.SelectedTab = this.tabCheck;
}
}
I don't know how to setup the for each loop to check the list box / list entries. Please do help if you know how.
Here is the code on how I add into the list box:
List.Add(new Student(txtName.Text, txtLastName.Text, txtClassroom.Text, dateDay.Value.ToString("dd.MM.yyyy")));
Here is the way the class returns the value that gets added into the list box:
public string StudentAdd()
{
return $"{this.Name} {this.LastName} | {this.Clasroom} | {this.DateOfLeave}";
}
Edited: changed OsveziPregledDijaka() -> RefreshCheck, added RefreshCheck function to code.
You can use LINQ expression to see if the item is exists or not.
if(ListBox.Items.Any(i=>i.Name == txtName.Text && i.LastName == txtLastName.Text && i.ClassRoom == txtClassRoom.Text)
{
//Show MessageBox
}
You can override the Equals operator in the Student class, then use the Contains method to check the list.
public override bool Equals(object obj)
{
if (obj == null || !(obj is Student student))
{
return false;
}
return Name == student.Name && LastName == student.LastName && Classroom == student.Classroom && DateDay == student.DateDay;
}
Then to check the item:
if (!ListBox.Items.Contains(student))
{
ListBox.Items.Add(student);
}
else
{
MessageBox.Show("You didnt fill out all the text boxes.", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
You need to search into the strings displayed by the listbox. But the code above uses ListBox.Items.ToString() and this will be just the ListBox class name not the individual strings displayed by the ListBox.
So, assuming that your listbox shows the info about the studend using firstname, lastname and classroom, you need to build a string like the one displayed by the items collection
string searchFor = $"{txtName.Text} {txtLastName.Text} {txtClassRoom.Text}";
and with that string search the items collection (no need to call Cast())
if (boxListBox.Items.Contains(searchFor))
....
else
....
Here the complete event click handler rewritten
private void btnAdding_Click(object sender, EventArgs e)
{
if (txtName.Text != "" && txtLastName.Text != "" && txtClassroom.Text != "" )
{
string searchFor = $"{txtName.Text} {txtLastName.Text} {txtClassRoom.Text}";
if (boxListBox.Items.Contains(searchFor))
{
MessageBox.Show("This entry already exists.", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
List.Add(new Student(txtName.Text, txtLastName.Text, txtClassroom.Text, dateDay.Value.ToString("dd.MM.yyyy")));
RefreshCheck();
}
}
else
{
MessageBox.Show("You didnt fill out all the text boxes.", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
I'm working on an interface for a user to enter a name, number, and initial balance to create an account. Then allowing the user to withdraw or deposit money through a class called Customer with Deposit and Withdrawal methods.
I've done the account creation part successfully. The problem is that I've created a new object called cust1 when the account successfully completes, but that object cannot be accessed when the user presses the button to apply the deposit or withdrawal.
the interface
The full code as of right now: http://pastebin.com/6HHdMLV1
The object declaration is at the bottom of this code here, this is the method for when the user presses the account create button.
private void CreateAccountButton_Click(object sender, EventArgs e)
{
string fullName = " ";
int accountNumber = 0;
double initialBalance = 0.00;
Boolean validName = false;
Boolean validAccount = false;
Boolean validBalance = false;
if (string.IsNullOrWhiteSpace(AccountNameInput.Text))
{
MessageBox.Show("Please enter your full name.", "Error",
MessageBoxButtons.OKCancel);
}
else if(Regex.IsMatch(AccountNameInput.Text, #"^[a-zA-Z ]+$"))
{
if(AccountNameInput.Text.Contains(" "))
{
fullName = AccountNameInput.Text;
validName = true;
}
else
{
MessageBox.Show("Full name must contain a space.", "Error",
MessageBoxButtons.OKCancel);
}
}
else
{
MessageBox.Show("Name must not contain numbers or special characters.", "Error",
MessageBoxButtons.OKCancel);
}
if (string.IsNullOrWhiteSpace(AccountNumberInput.Text))
{
MessageBox.Show("Please enter your account number", "Error",
MessageBoxButtons.OKCancel);
}
else if(Regex.IsMatch(AccountNumberInput.Text, #"^[0-9]+$"))
{
accountNumber = Convert.ToInt32(AccountNumberInput.Text);
validAccount = true;
}
else
{
MessageBox.Show("Must contain only numbers.", "Error",
MessageBoxButtons.OKCancel);
}
if (string.IsNullOrWhiteSpace(InitialBalanceInput.Text))
{
MessageBox.Show("Please enter your initial balance", "Error",
MessageBoxButtons.OKCancel);
}
else if (Regex.IsMatch(AccountNumberInput.Text, #"^[0-9.]+$"))
{
initialBalance = Math.Round(Convert.ToDouble(InitialBalanceInput.Text),2);
validBalance = true;
}
else
{
MessageBox.Show("Initial balance must contain only numbers and a decimal point.", "Error",
MessageBoxButtons.OKCancel);
}
if(validName == true && validAccount == true && validBalance == true)
{
AccountBalanceDisplay.Text = "$" + Convert.ToString(initialBalance);
Customer cust1 = new Customer(fullName, accountNumber, initialBalance);
}
}
And here is the method that isn't able to access the cust1 object.
private void ApplyButton_Click(object sender, EventArgs e)
{
double userInput = Convert.ToDouble(AmountInput.Text);
if (DepositRButton.Checked)
{
cust1.Deposit(userInput);
}
}
You simply need to add a reference to the object outside of the method that you create it in.
private cust1;
private void CreateAccountButton_Click(object sender, EventArgs e)
{
//Your code
}
And now you can just replace
Customer cust1 = new Customer(fullName, accountNumber, initialBalance);
with
cust1 = new Customer(fullName, accountNumber, initialBalance);
Assuming that you need more than one customer you might want to use a list. This way you can just create the object like you did and add it to that list.
List<Customer> CustomerList = new List<Customer>();
private void CreateAccountButton_Click(object sender, EventArgs e)
{
//Rest of your code
if(validName == true && validAccount == true && validBalance == true)
{
AccountBalanceDisplay.Text = "$" + Convert.ToString(initialBalance);
Customer cust1 = new Customer(fullName, accountNumber, initialBalance);
CustomerList.Add(cust1)
}
And you can access the customer by it's position on the list:
private void ApplyButton_Click(object sender, EventArgs e)
{
double userInput = Convert.ToDouble(AmountInput.Text);
if (DepositRButton.Checked)
{
CustomerList[0].Deposit(userInput);
}
}
Here, I developed WPF application using a OLEDB (Access) database and rdlc report. Here, I have problem in Datagrid. THis application run perfect but when I search any record and it gives me error "Please select the record which you want to print !!!". When I debug this application I know about it . When I search any record that time checkbox value is set automatically false. So that's the problem. So please suggest me what i should do? May i change searching code or not and If i change it then please recommend me any good way. Thanks in Advance. Please see my delete button code because when i click on delete but then after it creates this problems.
Below Code is for Searching ChequeName :-
private void txtChequeName_TextChanged(object sender, TextChangedEventArgs e)
{
System.Windows.Controls.TextBox t = (System.Windows.Controls.TextBox)sender;
string filter = t.Text.ToUpper();
ICollectionView cv = CollectionViewSource.GetDefaultView(dgDataArea.ItemsSource);
if (filter == "")
cv.Filter = null;
else
{
cv.Filter = o =>
{
BankMaster p = o as BankMaster;
//if (t.Name == "txtFirstName")
//return (p.FirstName == filter);
return (p.ChequeName.ToUpper().StartsWith(filter));
};
}
}
This below code is for print data :-
private void ImgPrint_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
List<BankMaster> bmlist = dgDataArea.ItemsSource as List<BankMaster>;
if (bmlist != null)
{
foreach (var item in bmlist)
{
if (item.CheckAll == false)
{
MessageBox.Show("Please select the record which you want to print !!!", "Error In Selecting Record", MessageBoxButton.OK, MessageBoxImage.Error);
break;
}
else
{
ChequePrintReport chreport = new ChequePrintReport();
B_SQUARE_System.Core.Utility.GeneralDeclaration.isGridSelectionChange = true;
chreport.ChequeInfo__OnSaved += adddata_BankInfo_OnSaved;
chreport.isEditMode = true;
chreport.currentSelectedItem = bmlist;
chreport.ShowDialog();
break;
}
}
}
}
private void Imgdelete_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
List<BankMaster> bmlist = dgDataArea.ItemsSource as List<BankMaster>;
String msg = "Are you sure you want to delete selected rows ? ";
int count = 0;
if (bmlist != null)
{
foreach (var item in bmlist)
{
if (item.CheckAll == false)
{
MessageBox.Show("Please select the record which you want to delete !!!", "Error In Selecting Record", MessageBoxButton.OK, MessageBoxImage.Error);
break;
}
else
{
if (MessageBox.Show(msg, "Delete Cheque Data", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
{
foreach (var items in bmlist)
{
if (items.CheckAll == true)
{
bmservices.deleteBankMasterInfo(items.Bank_ID);
count++;
}
}
System.Windows.MessageBox.Show("You deleted " + " " + count + " " + "rows.", "Total Deleted Row", MessageBoxButton.OK, MessageBoxImage.Information);
BankMaster_Loaded(sender, e);
}
break;
}
break;
}
}
Application Output
The problem is with your item.CheckAll condition inside your loops. You should not use the else statement here because all the items are not mostly checked-so the else code will run for some items.
Change the code inside the foreach loops like this:
bool printed = false;
foreach (var item in bmlist)
{
if (item.CheckAll)
{
//Place the Printing code here
printed=true;
}
if (printed == false)
{
//Place the Error message here
}
}
Change the delete code in similar way...
//code for confirm password text box:
private void txtRegPassConfirm_TextChanged_1(object sender, EventArgs e)
{
if (txtRegPassConfirm.Text != txtRegPass.Text)
{
MessageBox.Show("Passwords do not match");
txtRegPassConfirm.Clear();
}
else
{
MessageBox.Show("textbox can not be empty");
}
}
//code for text box Password:
private void txtRegPass_TextChanged(object sender, EventArgs e)
{
if (txtRegPass.Text.Length < 8)
{
MessageBox.Show("Password must be at least 8 characters long");
txtRegPassConfirm.Clear();
}
// code for text box Email:
private void txtRegEmail_TextChanged_1(object sender, EventArgs e)
{
string c = ConfigurationManager.ConnectionStrings["Constr"].ConnectionString;
SqlConnection con = new SqlConnection(c);
con.Open();
SqlCommand cmd = new SqlCommand("EmailReg", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Email", this.txtRegEmail.Text);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
if (dr.HasRows == true)
{
MessageBox.Show("Email = " + dr[4].ToString() + "is Already exist");
txtRegEmail.Clear();
break;
}
Regex r = new Regex("^[a-zA-Z0-9){1,20}#[a-zA-Z0-9){1,20}.[a-zA-Z]{2,3}$");
if (!r.IsMatch(txtRegEmail.Text))
{
txtRegEmail.Clear();
MessageBox.Show("incorrect formate");
}
}
}
//code for button Registration:
private void btnRegistration_Click_1(object sender, EventArgs e)
{
string c = ConfigurationManager.ConnectionStrings["Constr"].ConnectionString;
SqlConnection con = new SqlConnection(c);
con.Open();
SqlCommand cmd = new SqlCommand("RegistrationForm", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#UserName", txtRegUserN.Text);
cmd.Parameters.AddWithValue("#Password", txtRegPass.Text);
cmd.Parameters.AddWithValue("#Confirm", txtRegPassConfirm.Text);
cmd.Parameters.AddWithValue("#Email", txtRegEmail.Text);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
if (dr.HasRows == true)
{
MessageBox.Show("Data Inserted Succesfully");
}
}
if (dr.HasRows == false)
{
MessageBox.Show("Access Denied, enter the correct fields");
}
else
{
MessageBox.Show("Enter correct info");
}
}
When I execute the application and enter the password in a confirm text box, it shows me the message box on entering the first character 'Password don't match'. As well as shows me message in the Password text box 'Password must be at least 8 characters long'. And as same as in the Email text box and I want to apply the Regex but not working. I moved my code in the email section but, it shows me the 'Email is invalid' regex message box. Now, tell me what I can do get the message box when I enter the mismatch words not on entering the first character.
Main Problem:
You are checking your validation rules in TextChanged event of your text boxes. Some options that may help you to perform validation is listed here:
Option1: validate in Click Event of Button
You can check for validations in Click event of your register button some thing like this:
private void registerButton_Click(object sender, EventArgs e)
{
//Check for password length
if (txtRegPass.Text.Length < 8)
{
MessageBox.Show("Password must be at least 8 characters long");
txtRegPass.Focus();
return;
}
//Check for other validations
//...
// don't forget to return; if the state is not valid
//If the code execution reaches here, it means all validation have been passed
//So you can save data here.
}
Option 2: Use Validating Event and ErrorProvider
As a better solution, you can use an ErrorProvider. Put an error provider in form and handle Validatin event of your TextBoxes and set error for that control.
Then in Click event of your register button you can check if there is any validation error or not.
and here a screenshot:
private void ValidationTest_Load(object sender, EventArgs e)
{
this.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange;
}
private void passwordTextBox_Validating(object sender, CancelEventArgs e)
{
if (this.passwordTextBox.TextLength < 8)
{
this.errorProvider1.SetError(this.passwordTextBox, "Password must be at least 8 character");
e.Cancel = true;
}
else
{
this.errorProvider1.SetError(this.passwordTextBox, "");
}
}
private void confirmTextBox_Validating(object sender, CancelEventArgs e)
{
if (this.confirmTextBox.Text != this.passwordTextBox.Text)
{
this.errorProvider1.SetError(this.confirmTextBox, "Password and Confirm must be the same");
e.Cancel = true;
}
else
{
this.errorProvider1.SetError(this.confirmTextBox, "");
}
}
private void registerButton_Click(object sender, EventArgs e)
{
if (this.ValidateChildren())
{
//Do registration here
}
else
{
var listOfErrors = this.errorProvider1.ContainerControl.Controls
.Cast<Control>()
.Select(c => this.errorProvider1.GetError(c))
.Where(s => !string.IsNullOrEmpty(s))
.ToList();
MessageBox.Show("please correct validation errors:\n - " +
string.Join("\n - ", listOfErrors.ToArray()),
"Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Because you are using TextChanged event and it raises every time you change the Text. You should check this on click of your button Register.
Not only this one, your all validations should be checked on the button click.
For the help of user, you can use a Label to show the the message while user is typing something, rather showing a MessageBox. That will be a smooth experience for user.
Here is your solution
private void btnRegistration_Click_1(object sender, EventArgs e)
{
if (txtRegPassConfirm.Text != txtRegPass.Text)
{
MessageBox.Show("Passwords do not match");
txtRegPassConfirm.Clear();
return;
}
else
{
if (txtRegPass.Text.Length < 8)
{
MessageBox.Show("Password must be at least 8 characters long");
txtRegPassConfirm.Clear();
return;
}
}
//put your next code as it is which you wrote in this click event
}
Thanks
The problem is you put your validation code in txtRegPassConfirm_TextChanged_1 function. As the name of the function said, that function will be triggered whenever the text in txtRegPassConfirm textbox changed. That's why you get the MessageBox when you first type.
To solve your problem, put your validation code in the Click event of Register button instead of TextChanged event of each textbox.
Another better solution is: use Error Provider Control to show your error instead of using MessageBox. To know more about it, take a look at MSDN.
The validation can also be done while moving to the next text box(Validation of previous text box input) by pressing tab or by mouse click. This can be done in the textbox events Leave or Enter.
private void textBox1_Leave(object sender, EventArgs e) // This event is triggered while leaving the textbox1
{
if ("a" != textBox1.Text)
{
MessageBox.Show("Invalid");
}
}
private void textBox2_Enter(object sender, EventArgs e)// This event is triggered while entering the textbox2
{
if ("a" != textBox1.Text) //Content of textbox1 is validated
{
MessageBox.Show("Invalid");
}
}
Hey so I have the following code which should throw up the errors if the text boxes are empty but it doesn't it just carries on with what it would do were they not and adds an item with 0 or whatever to the list instead, is there a problem with my code?
private void BtnAdd_Click(object sender, EventArgs e)
{
try
{
theVisit.name = txtName.Text;
theVisit.address = txtAddress.Text;
theVisit.arrival = DateTime.Parse(txtArrival.Text);
//Update theVisit object to reflect any changes made by the user
this.Hide();
//Hide the form
}
catch (Exception)
{
if (txtName.Text == "")
MessageBox.Show("please enter a customer name");
if(txtAddress.Text == "")
MessageBox.Show("Please enter a customer address");
if(txtArrival.Text == "")
MessageBox.Show("Please enter an arrival time");
}
NEW
if (txtName.Text == "" || txtAddress.Text == "" || txtArrival.Text == "")
MessageBox.Show(" Please enter a value into all boxes");
else
theVisit.name = txtName.Text;
theVisit.address = txtAddress.Text;
theVisit.arrival = DateTime.Parse(txtArrival.Text);
//Update theVisit object to reflect any changes made by the user
The try-catch-statement is used to catch and handle exceptions. An exception can be thrown, if an index is out of bounds, if members of a variable set to null are accessed, and in many other situations. A TextBox being empty is not an error by itself and does not throw an exception.
I suggest you to use a completely different approach. Add an ErrorProvider to your form. You find it in the toolbox in the section "Components". Now you can add the following code to your form:
private HashSet<Control> errorControls = new HashSet<Control>();
private void ValidateTextBox(object sender, EventArgs e)
{
var textBox = sender as TextBox;
if (textBox.Text == "") {
errorProvider1.SetError(textBox, (string)textBox.Tag);
errorControls.Add(textBox);
} else {
errorProvider1.SetError(textBox, null);
errorControls.Remove(textBox);
}
btnAdd.Enabled = errorControls.Count == 0;
}
private void Form1_Load(object sender, EventArgs e)
{
txtName.Tag = "Please enter a customer name";
txtAddress.Tag = "Please enter a customer address";
errorProvider1.BlinkStyle = ErrorBlinkStyle.NeverBlink;
ValidateTextBox(txtName, EventArgs.Empty);
ValidateTextBox(txtAddress, EventArgs.Empty);
}
Select the ValidateTextBox method as error handler for the TextChanged event of all your textboxes. Insert the desired message in the Tag property of the textboxes. Set the BlinkStyle property of the ErrorProvider to ErrorBlinkStyle.NeverBlink. You can do these settings in code or in the form designer.
Now a red error symbol will appear next to empty textboxes. If you hoover the mouse over them, a tooltip with the error message will appear.
UPDATE
I updated the code above to automatically disable or enable the "Add"-button. Therefore I added a HashSet that contains all the controls currently being in an error state. If the set is empty the button is enabled, otherwise disabled.
You should always be avoiding try catch where possible, because of performance hits see example below:
//set name
if(string.IsNullOrEmpty(txtName.Text)) MessageBox.Show("please enter a customer name");
else theVisit.name = txtName.Text;
//set address
if(string.IsNullOrEmpty(txtAddress.Text)) MessageBox.Show("please enter a customer address");
else theVisit.address = txtAddress.Text;
//set arrival time
if(string.IsNullOrEmpty(txtArrival.Text)) MessageBox.Show("please enter an arrival time");
else {
DateTime dt = default(DateTime);
bool successParse = DateTime.TryParse(txtArrival.Text, out dt);
if(!successParse) MessageBox.Show("please enter a valid arrival time");
else theVisit.arrival = dt;
}