|
Ah yes, I can see how this works ... but there's a problem (and my fault for not fully describing my structure) . . .
I have a calculate button that is used at the end of entering in all the numbers, which converts each textbox.text value into another variable i.e. textboxnum using Convert.ToDouble(textbox.Text)
All of the calcs are then done with these variables, then the results are outputted to a set of textboxe's using .ToString("N2")
This is why I was thinking that using regex's on the user input validation side was the best approach ! - but I am a newbie
Also, I assume your code still goes in the leave or text_changed event ?
Also 2, is it possible to use this method for validating the 0.1 to 2.9 ranged input ?
Cheers
Damian
|
|
|
|
|
Don't bother with a regex.
Change the int.TryParse to double.TryParse (and the values to doubles as well) and it validates and converts them at the same time.
When they are all validated, you have a collections of doubles you can use for your calculations, and yes, the validations can be floating point:
double value;
if (!(double.TryParse(myTextBox.Text, out value) && value >= 0.1 && value <= 2.9))
{
MessageBox.Show("Please enter a number between 0.1 and 2.9");
...
return;
}
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
ah right O, i'm on it !
I'll report back in er a few hours !
Cheers
|
|
|
|
|
OK .. got a bit of a problem now
As the tryparse method can't be on the text_changed event (it throws the error message as soon as I type in 0 for 0.6 - it also throws the same message when you backspace to delete an incorrect entry - so not helpful.
So I've switched it to the Leave event ... the issue with this is that now I can't tab to another textbox without the error message popping up, BUT more importantly I can no longer close the application using the Exit button ! it throws up the error message of the first textbox !
This was the first issue I had when I started writing this app, and I resolved it by having the validation on the text_changed event and the processing part on the leave event.
So how to I get round this issue now ?
Also I am a bit stumped on how I now do calculations on the values in the text boxes, I have 2 text boxes that are basically maximum and minimum quantities, and previously when both of these were filled, a third text box would display the difference i.e.
nicshotsize.Text = (Convert.ToInt32(totalsize.Text) - Convert.ToInt32(shortfillsize.Text)).ToString();
But now that i'm using the double.TryParse(textbox.text ... method, how do I reference those values.
In PowerShell world it would be textbox.Value , but this does not seem to exist ! ??
|
|
|
|
|
Well this is great !! .. my code \ app is now totally broken, I can't go back (stupidly did not make a backup of if before embarking on these suggested changes)and I can't go forward !
I've basically lost 3 days of time that I put into this
Might as well trash this as well as any ideas of wanting to learn C#
Not happy
|
|
|
|
|
Damian Bz wrote: Might as well trash this as well as any ideas of wanting to learn C# Why? C# is one of the easier programming languages to learn, but it looks to me like you are trying to run before you can walk. Get hold of a good study guide and learn the language first, and try the simpler samples. Charles Petzold has written some of the best books available on programming in Windows, and .NET Book Zero[^] is a great starting point for C#.
|
|
|
|
|
That's a problem with your UI, rather than the code: it will happen like that whatever you do to validate, particularly if you validate in the TextChanged event and use MessageBoxes.
A better approach might be the way some website registration pages do it: a label beside the textbox (with foreground colour Red) that you put error messages into instead of using message boxes.
That way, the user can see the problem without being interrupted all the time.
When you do the conversion, store the results in class level private variables, and just execute the code:
nicshotsize.Text = (totalSize - shortFillSize).ToString();
Or better: don't use two TextBoxes at all, but NumericUpDowns instead - which won't let him enter "bad data" so it doesn't need validation.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Well .. OK, I may have over reacted !, but I WAS very miffed that my code was seemingly trashed.
I spent a good few hours last night piecing it back together and rectifying all of the issues.
Visual Studio is really not helpful when it says that your code is all fluffed, and to REALLY help you i'm going to block you from seeing your form layout (thanks for that!)
Anyway, I got it back to where I was yesterday, then removed all the RegEx stuff and lots of if - else's to do the validation.
I wasn't really up to figuring out the tryparse millarky last night, but I'm personally pretty please with what I have come up with.
It may not be the right way of doing it, and i'm sure you guys\ladies could do it in half the code, but nethermind !
Here's a snippet of just one of the textbox event functions:
private void totalsize_TextChanged(object sender, EventArgs e)
{
int ts;
if (string.IsNullOrEmpty(totalsize.Text))
;
else
{
if ((totalsize.Text.All(chr => char.IsLetter(chr))) | (totalsize.Text.Contains(".")))
{
MessageBox.Show("Please enter only whole numbers between 1 and 500");
totalsize.Clear();
totalsize.Focus();
}
else
{
ts = Convert.ToInt32(totalsize.Text);
if (!(ts >= 1 && ts <= 500))
{
MessageBox.Show("Please enter only whole numbers between 1 and 500");
totalsize.Clear();
totalsize.Focus();
}
}
}
}
private void totalsize_Leave(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(totalsize.Text) && !string.IsNullOrEmpty(shortfillsize.Text))
nicshotsize.Text = (Convert.ToInt32(totalsize.Text) - Convert.ToInt32(shortfillsize.Text)).ToString();
if (!string.IsNullOrEmpty(totalsize.Text))
totalsizenum = Convert.ToDouble(totalsize.Text);
}
The first <if> statement //do nothing allows the user to move out of the textbox without causing an error. (there are other buttons that display help text etc. that the user may want to explore before typing in any numbers)
The first <else> <if> block checks to make sure that no alphabet or period character is entered (the first two textboxes need to be whole numbers only)
As soon as an illegal character is entered, the message box pops up with a warning.
The next <else> block checks that the number entered is in the right range.
That's the end of the TextChanged event.
Once the user moves out this Textbox the _Leave event kicks in.
This then checks if this Textbox + the next Textbox has a value entered, and if so does a very basic deduct one from the other and display the result in a read only Textbox.
The second Textbox has almost the same code.
The idea of this is that this way it allows the user to enter in the values in any order they feel like.
This is probably the simplest set of event functions, there are others that auto fill other Textboxes, for instance when typing in a percentage value in one box, another box is showing the reverse percentage, again these boxes can be used in any order, whatever goes in one fills the other.
The Calculate button then does a final check on all of the Textboxes to make sure they are all filled.
I'm about to start writing extra code to highlight any boxes that are missing data.
On the final calculations, I convert most of the Textbox values to double's, create temp variables that match them, do the calcs on these, then on the actual Textboxes I'm using this:
Textbox.Text = Math.Round(Textboxtmp, 2).ToString();
And all is well in the world ! well apart from the dog who wishes I was paying him more attention !
And I've also installed DPack tools that has a handy feature of backing up the project automatically and manually !!
So I'm back on track, and ready to keep on learning.
Sorry for throwing my toy out of the pram earlier
Cheers
Damian
|
|
|
|
|
You can suppress certain keystrokes in the first place without having to resort to some field edits. The following is straight from the docs. (BTW all this is easier in WPF).
private bool nonNumberEntered = false;
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
nonNumberEntered = false;
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
{
if(e.KeyCode != Keys.Back)
{
nonNumberEntered = true;
}
}
}
if (Control.ModifierKeys == Keys.Shift) {
nonNumberEntered = true;
}
}
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (nonNumberEntered == true)
{
e.Handled = true;
}
}
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Thanks Gerry,
I'd actually stumbled upon a similar but shorter solution and was working on that before I read your comment.
void textBoxSample_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = Char.IsPunctuation(e.KeyChar) ||
Char.IsSeparator(e.KeyChar) ||
Char.IsSymbol(e.KeyChar);
}
This works really well when I want to stop any non whole numerical value, and I still use this in conjunction with the Text_Changed event to check for correct range etc.
Where this goes wrong is when I need to allow a "." i.e. 7.2 as the Char.IsPunctuation blocks the "."
But if I remove Char.IsPunctuation it allows characters like \ / ? which crashes my app !
How can I get round this either by modifying what I have or using your suggested method or other ?
Here's what I have:
private void nicstrength_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = Char.IsSeparator(e.KeyChar) || Char.IsSymbol(e.KeyChar);
}
private void nicstrength_TextChanged(object sender, EventArgs e)
{
double ns;
if (string.IsNullOrEmpty(nicstrength.Text))
;
else
{
if ((nicstrength.Text.Any(chr => char.IsLetter(chr))) || (nicstrength.Text.StartsWith(".")))
{
MessageBox.Show("Please enter a number between 1 and 10 inc decimal points i.e 7.2");
nicstrength.Clear();
nicstrength.Focus();
}
else
{
ns = Convert.ToDouble(nicstrength.Text);
if (!(ns >= 1 && ns <= 10))
{
MessageBox.Show("Please enter a number between 1 and 10 inc decimal points i.e 7.2");
nicstrength.Clear();
nicstrength.Focus();
}
}
}
}
Many thanks
Damian
|
|
|
|
|
OK fixed it ! probably viewed as clunky, but it works !
Created this:
private readonly char[] notallowed = { '!', '"', '#', '%', '&', '\'', '(', ')', '*', ',', '-', '/', ':', ';', '?', '@', '[', '\\', ']', '_', '{', '}', '+' };
Then in the functions where I need to allow the use of a "." but no other non numerical characters i've added this:
if ((nicstrength.Text.Any(chr => char.IsLetter(chr))) || (nicstrength.Text.StartsWith(".")) || (nicstrength.Text.IndexOfAny(notallowed) != -1))
I have now tested every single textbox, and none will allow any incorrect entries .. yay.
I think my first C# app is done and ready to meet the world !
Many thanks for the help thus far, I'm sure i'll need plenty more
Cheers
Damian
|
|
|
|
|
Myself, I found keyboard handling easier when I only "allowed" certain characters; versus trying to find what to "exclude".
E.g. for most "numeric" textboxes, I simply just "allow" digits and possibly a decimal; with a few navigation keys thrown in.
It's easier to "fix" a key that is "not working" (i.e. include it), than to stop all the "others", individually, from not working (IMO).
(So, default to "handled" for all except the "good" keys).
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Hi everybody,
I would like to address at run time datagrid cells individually and change their content depending on some conditions.
Could someone give me some directions on this topic?
Best regards,
RV
|
|
|
|
|
|
Thank you for your reply,
Is not this approach somehow more suitable for WinForm projects?
I'm actually developing my application in the WPF c# environment.
Best regards,
RV
|
|
|
|
|
If you're doing this using WPF, you really should use MVVM. Then you would manipulate the data via the ViewModel.
This space for rent
|
|
|
|
|
Thank Pete you for your advice. I will try to find out how to proceed using MVVM.
|
|
|
|
|
Member 13511312 wrote: I'm actually developing my application in the WPF c# environment. And we are supposed to guess that?
|
|
|
|
|
Sorry for having forgotten to mention this detail.
|
|
|
|
|
Is there any difference between:
DataHelpers dh = new DataHelpers {};
and
DataHelpers dh = new DataHelpers ();
|
|
|
|
|
Not as written; both redundant in this case.
Otherwise, {...} is used to initialize fields / properties; whereas (...) might be used to pass parameters to a constructor.
Other options: ... (...){...}
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Thanks for the reply. If both are redundant, why am I getting a red line in Visual Studio?
|
|
|
|
|
You post "fragments" and expect comprehensive answers ...
I suspect you spent 0 time looking up either topic.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
That kind of comment makes people who are just starting out, not want to ask questions. Maybe if you're feedback is neither helpful nor constructive, you might consider not being so "helpful."
|
|
|
|
|
Hi Rick, your profile here on CP suggests you are not "just starting out."
Nothing "wrong" with that, but I do wonder if you are taking the time to do some basic research before posting. CodeProject is "bursting at the seams" with relevant content on almost any topic ... ditto StackOverflow.
cheers, Bill
«While I complain of being able to see only a shadow of the past, I may be insensitive to reality as it is now, since I'm not at a stage of development where I'm capable of seeing it.» Claude Levi-Strauss (Tristes Tropiques, 1955)
|
|
|
|
|