Validate two textboxes (C #) - c#

I have two textboxes, which prompts the user to enter an integer in each of them. I already have the code all done (code to validate if the texboxes are not empty, if only integers are entered and if the number inserted in the 2nd texbox is greater than the number entered in the 1st texbox.
I leave here a simple example of my code (I already have all the code done):
private async void generate_Click(object sender, RoutedEventArgs e)
{
if (String.IsNullOrWhiteSpace(min.Text) || String.IsNullOrWhiteSpace(max.Text))
{
// I already have the code done ...
// error message
}
else
{
// I already have the code done ...
// Here it does the operation with the two numbers entered
}
}
private async void min_TextChanged(object sender, TextChangedEventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(min.Text, "[^0-9]"))
{
// I already have the code done ...
// error message
}
}
private async void max_TextChanged(object sender, TextChangedEventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(max.Text, "[^0-9]"))
{
// I already have the code done ...
// error message
}
}
I only have one question: Where do I put the code (I already have this code done) to verify that the number entered in the 2nd textbox is greater than the number entered in the 1st texbox? This is my question.
Update: I just want to know where I put the code:
if (maxValue < minValue)
{
// I already have the code done ...
// error message
}

Encapsulate all of this validation logic in a function the returns a bool
private bool IsValid ()
{
if (String.IsNullOrWhiteSpace(min.Text) || String.IsNullOrWhiteSpace(max.Text))
{
// return false any where the input is not valid
}
}
then use an if statment inside Your Button click Event Handler
if (IsValid())
{
//Code To Check If Max is Bigger Than min
}
this Way You Can Easily Call The IsVaild Function To Check For Empty String
You Can Also Encapsulate The Logic To Validate The Bigger Number in Another function if u gonna use it alot
Hope I Fully Understood You

If your confusion is only where to put the verification code of the number entered in the 2nd textbox is greater than the number entered in the 1st textbox, you can simply check this after the button click. Here's the sample:
private async void generate_Click(object sender, RoutedEventArgs e)
{
if (String.IsNullOrWhiteSpace(min.Text) || String.IsNullOrWhiteSpace(max.Text))
{
await new MessageDialog("Text boxes cannot be empty").ShowAsync();
return;
}
if (Convert.ToInt32(max.Text) < Convert.ToInt32(min.Text))
{
await new MessageDialog("1st one is bigger").ShowAsync();
//you may do as you want, showing a message box is just a sample
}
else
{
await new MessageDialog("2nd one is bigger").ShowAsync();
//you may do as you want, showing a message box is just a sample
}
}
And for your clarification onTextChanged events may be like this:
private async void min_TextChanged(object sender, TextChangedEventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(min.Text, "[^0-9]") )
{
await new MessageDialog("Enter numbers only.").ShowAsync();
//you may do as you want, showing a message box is just a sample
}
}
private async void max_TextChanged(object sender, TextChangedEventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(max.Text, "[^0-9]"))
{
await new MessageDialog("Enter numbers only.").ShowAsync();
//you may do as you want, showing a message box is just a sample
}
}
So here the summary is, if the textboxes are empty it will show a warning and return. And after the user finishes the input number and presses the button it will check which number is bigger. And a warning will also showed if users give input rather than numbers. Hope this may help you.

Related

C# communication between forms bug

I'm working on a GUI for an admin interface for management of a student complex. Currently the GUI has a listbox with predefined 6 rules for the students. In the beginning of the code, I add them to a list
private void Form1_Load(object sender, EventArgs e)
{
foreach (string rule in lbRules.Items)
ruleList.Add(rule);
}
Then, the GUI provides the admin with an option to modify the rules. To do so he selects a rule from the listbox and clicks a "Modify" button, which opens another form:
private void BtnModify_Click(object sender, EventArgs e)
{
if (lbRules.SelectedItems.Count > 0)
{
selectedRule = lbRules.SelectedItem.ToString();
selectedIndex = lbRules.SelectedIndex;
selectedRuleNumber = selectedRule.Substring(0, 3);
selectedRule = selectedRule.Substring(6);
var rulesForm = new Rules();
rulesForm.Show();
}
}
On the second form load event I get the rule's text and number:
private void Rules_Load(object sender, EventArgs e)
{
tbRule.Text = Form1.selectedRuleNumber;
tbModifyRule.Text = Form1.selectedRule;
}
The text gets added to a RichTextBox, from where the rule can be edited.
Then the admin clicks a "Save" button, which gets the edited text from the RichTextBox(tbModifyRule) and adds it to a static ruleList in form1, sets a static boolean from form1 to true. Afterwards the second form gets closed:
private void BtnSave_Click(object sender, EventArgs e)
{
saveRule = Form1.selectedRuleNumber + " - " + tbModifyRule.Text;
Form1.ruleList.Insert(Form1.selectedIndex, saveRule);
Form1.ruleList.RemoveAt(Form1.selectedIndex+1);
Form1.formOpen = true;
this.Dispose();
}
At this point we are back to form1, in which we have a timer with timer_tick event. In there we check whether the boolean formOpen is true (which it is set before closing form2). Inside the if statement we clear the listbox and add each rule from the ruleList (previously edited in form2) to the listbox, then sets the formOpen back to false so it doesn't get executed all the time:
if (formOpen)
{
lbRules.Items.Clear();
foreach (string item in ruleList)
lbRules.Items.Add(item);
}
formOpen = false;
Now this is really weird, and at this point makes absolutely no sense to me, since I tried debugging it for over an hour, trying different ways, which also led me to mysterious wonders of WHY TF IT WORKS WHENEVER IT WANTS...
So this works randomly, like it would work the first time, the second and third times it won't. Or vice versa. It's all random.
Strangely, I tried adding a breakpoint on the
lbRules.Items.Add(item);
in the foreach loop, so it stops on each item. And I actually saw the changed rule getting added from the ruleList into the listBox, however in the end it was not there.
And weirdly enough, I also tried adding the text from form2 in the listBox in form1, without using a list, but for whatever odd reason, I use the int selectedIndex, which gets the index of the selected item from the BtnModify_Click event to insert the text in that particular index, but this very index gets RANDOMLY set to bloody 0 after form2 closes.
hence, it again works from time to time, because at some tries it doesn't get set to 0 and it works.
if (formOpen)
{
selectedRule = Rules.saveRule;
lbRules.Items.Insert(selectedIndex, selectedRule);
lbRules.Items.RemoveAt(selectedIndex+1);
}
formOpen = false;
I don't assign value to this integer ANYWHERE else in the code.
I really tried digging some sense, but I hit a solid hard rock.
Any help appreciated!
And thanks for the time!
edit1:
as requested - rest of the timer method
private void Timer1_Tick(object sender, EventArgs e)
{
foreach (string text in ws.messages)
message = text;
if (ws.messages.Count > 0)
{
if (message.Contains("comp"))
{
Complaints();
message = String.Empty;
ws.messages.Clear();
}
}
if (formOpen)
{
lbRules.Items.Clear();
foreach (string item in ruleList)
lbRules.Items.Add(item);
}
formOpen = false;
}
I would change your code to the following:
if (formOpen)
{
formOpen = false;
lbRules.Items.Clear();
foreach (string item in ruleList)
lbRules.Items.Add(item);
}
The issue with having the formOpen = false; outside the if statement is that there is a chance that once the user clicks the Save button the timer could be about to execute the formOpen = false instruction setting it to false making the code inside the If statement to never be executed.
I truly believe this is not random but just a timing issue due to complicated logic.
If I were you, I'd do a couple things:
Use a separate class for data exchange between forms, avoid using public static (I assume) form members for this.
Instead of a timer, subscribe to the Form.Closed event of RulesForm
This might make code flow a bit more predictable and allow you to find errors more easily.
Better yet, use the following pattern:
class Form1
{
private void BtnModify_Click(object sender, EventArgs e)
{
var ruleData = ..... //get current rule data
var rulesForm = new Rules();
rulesForm.SetData(ruleData); //pass initial state to the form
rulesForm.SaveChanges = this.ApplyRules; //pass a method which will be called on save
rulesForm.Show();
}
private bool ApplyRules(RuleData ruleData)
{
//do whatever you like with the rules here
return true;
}
}
class RuleForm
{
public void SetData(RuleData ruleData)
{
//initialize fields, etc
}
public Func<RuleData, bool> SaveChanges { get; set; }
private void BtnSave_Click(object sender, EventArgs e)
{
var ruleData = .... //get data from form fields
if(this.SaveChanges(ruleData))
this.Close();
}
}
class RuleData
{
//whatever data you need
}

C# Input string Error

I'm trying too get the users value entered and count down in seconds from it, but whenever I input anything and click the start button it says input string not in correct format. I've googled and googled and cannot figure out how to get the users input and parse or convert it into an int and countdown from it, whilst updating the label via timer of course.
I'm use to console applications still wrapping my head around the syntax...
using System;
using System.Windows.Forms;
namespace Countdown {
public partial class Form1 : Form
{
int seconds; string user; int test = 30;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void tmrCountdown_Tick(object sender, EventArgs e)
{
lblDisplay.Text = test.ToString();
if (test > 1)
{
lblDisplay.Text = test.ToString() + " Seconds Remaining";
}
else if (test == 1)
{
lblDisplay.Text = test.ToString() + " Second Remaining";
}
else
{
tmrCountdown.Stop();
}
test--;
}
public void btnStart_Click(object sender, EventArgs e)
{
int test = int.Parse(txtBoxInput.Text);
tmrCountdown.Start();
}
private void txtBoxInput_TextChanged(object sender, EventArgs e)
{
}
}
}
Error is at "int test = int.Parse(txtBoxInput.Text);"
Change Parse into TryParse and see what value can't be parsed:
public void btnStart_Click(object sender, EventArgs e)
{
if (int.TryParse(txtBoxInput.Text, out test))
// We succeed in parsing, so we continue with the timer
tmrCountdown.Start();
else {
// We failed in parsing
// Let's put keyboard focus on the problem text box...
if (txtBoxInput.CanFocus)
txtBoxInput.Focus();
// ... and report what's been happened
MessageBox.Show($"'{txtBoxInput.Text}' is not a valid integer value",
Application.ProductName,
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
}
There are two problems in your code.
The first one is the fact that you don't protect your code from invalid inputs. If you don't type something in the txtBoxInput or if you type text that cannot be converted to an integer you get the Invalid String Format Exception
The second problem is the variable test. You declare it locally inside the button click and given the fact that you don't get compilation errors then you are not setting the global class level variable with the same name that you are using in the timer Tick event.
So, use TryParse everytime you need to handle user inputs. This will not raise an exception in case of problems, but just return true or false. Finally do not re-declare the int test variable inside the button click, but use the global class level variable directly in the output of TryParse
public void btnStart_Click(object sender, EventArgs e)
{
// Try to convert the input in an integer. If this succeed you have
// the global variable _test_ set to converted text
if(!Int32.TryParse(txtBoxInput.Text, out test)
MessageBox.Show("Invalid input. Please type a number!");
else
tmrCountdown.Start();
}
try this code at your button
int test=Convert.ToInt32(txtBoxInput.Text);
tmrCountdown.Interval = test*1000; //have to multiply to 1000 since timer interval value is in milliseconds.
tmrCountdown.Start();
Just put integers in your textbox

Quantity button when null crashes windows store app

I created a windows store app that has two buttons that will allow my users to select amounts of pictures. The control works when they need to pick the amount but when they click the 'X' inside of the textbox if they want to clear it out and then pressed a button the app crashes.
When I debug I get this error on my block of code:
{"Input string was not in a correct format."}
private void PicturesSubtract_Click(object sender, RoutedEventArgs e)
{
int? value = Convert.ToInt32(this.Pic.Text);
if (value > 1)
{
value--;
}
this.Pic.Text = value.ToString();
}
I get the same error when trying to add or subtract the picture amount.
Any help on this error would be great.
This line throws your error
int? value = Convert.ToInt32(this.Pic.Text);
The reason for this is that Convert.ToInt32 assumes you have a valid integer, and throws an exception in EVERY other case, including null.
http://msdn.microsoft.com/en-us/library/system.convert%28v=vs.110%29.aspx
There are two options I would recommend
The first, null check your text value before doing anything else:
private void PicturesSubtract_Click(object sender, RoutedEventArgs e)
{
if(String.IsNullOrEmpty(this.Pic.Text))
return;
....
The second, use the Int.TryParse method:
private void PicturesSubtract_Click(object sender, RoutedEventArgs e)
{
int value;
if(int.TryParse(this.Pic.Text, out value))
{
//...Do Stuff, Value is stored at this point

Auto refresh labels as text boxes text input data into method

Here is my method that I' am trying to have automatically refresh my label. When I have my label as a click event...the answer refreshes and is correct.
private void Calculate()
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
strUtil1 = UtilRounded1.ToString() + "%";
}
Here is the Validated label event that does not update when text is changed in my text boxes.
private void lblUtil1_Validated(object sender, EventArgs e)
{
Calculate();
}
If this is correct...what am I missing? is there something I need to do on the text boxes that will trigger validation?
I have also tried a text changed event that yields the error cannot implicitly convert type void(or any type for that matter) to EventHandler. Here is the code.
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
lblUtil1.TextChanged += Calculate();
}
Any help is appreciated! I've been banging my head on my keyboard for a day now.
First at all, you have to handle events for the TextBox that you input value to calculate, such as when you change vale in the TextBox or validate it.
So if you have textBox1 then you should have this handling (trigger when value in textBox1 is changed)
private void textBox1_TextChanged(object sender, EventArgs e)
{
lblUtil1.Text = Calculate();
}
I assume that you want to display value in strUtil1 at the label lblUtil1, so you have to change your Calculate method like this
private string Calculate()
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
strUtil1 = UtilRounded1.ToString() + "%";
return strUtil1;
}
EDITED
This is a sample code for validate the required TextBoxes.
private void textBox1_Validating(object sender, CancelEventArgs e)
{
if (textBox1.Text == "")
{
e.Cancel = true;
lblUtil1.Text = "textBox1 is required!";
}
}
Try calling yourlabelname.Refresh() i.e like
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
lblUtil1.TextChanged = Calculate();
lblUtil1.Refresh();
}
or
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
Calculate();
lblUtil1.Refresh();
}
You need to do a couple things.
First, stop using "hungarian" notation. It's bad. It's bad for a lot of reasons. MS even says, "don't use hungarian" as most people get it wrong as your code shows. Instead, name your variables appropriately. For example, dblSG has absolutely zero meaning.
Second, please reread Michael's answer to your question from yesterday ( https://stackoverflow.com/a/20026642/2424 ). He did NOT say to use lblUtil1_Validated. He said to use TextBox_Validated. In other words, the event you should have your calculation run on is with the textbox fields on your form. He also suggested you just use the textboxes TextChanged events in order to cause the calculation to run as they are typing. Personally, I don't agree with that but whatever.
A third possible option is to simply go back to your original solution. Meaning, just run the calculation when the label is clicked. In which case you should refer back to your original question as Michael failed to answer it.

Textbox validation in a Windows Form

I want to put a validation that the user always enters a value in the textbox before submiting the form. But the check that I have put allows user to enter white spaces and continue submitting the form.
So, how to put the check so that the user in not able to submit the form if there are only white spaces in the textbox.
You can make your own custom validation function. This may be very naive, but somehow it will work.
private bool WithErrors()
{
if(textBox1.Text.Trim() == String.Empty)
return true; // Returns true if no input or only space is found
if(textBox2.Text.Trim() == String.Empty)
return true;
// Other textBoxes.
return false;
}
private void buttonSubmit_Click(object sender, EventArgs e)
{
if(WithErrors())
{
// Notify user for error.
}
else
{
// Do whatever here... Submit
}
}
in NET4.0 there is a nice function
if(string.IsNullOrWhiteSpace(textBox1.Text))
{
//raise your validation exception
}
else {
//go to submit
}
It can be easily be done using error provider here is the code.Error Provider you can find in your toolbox.
private void btnsubmit_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtname.Text))
{
txtname.Focus();
errorProvider1.SetError(txtname, "Please Enter User Name");
}
if (string.IsNullOrEmpty(txtroll.Text)) {
txtroll.Focus();
errorProvider1.SetError(txtroll, "Please Enter Student Roll NO");
}
}
Here is output image

Categories