|
Pete O'Hanlon wrote: you cannot declare a class and namespace with the same name; I respectfully suggest this is a case where C# (VS 2017, 4.7.1, Debug, error check level #4) ... still ... lets you "get away with murder:" this will compile and run:
namespace SomeClass
{
public class SomeClass
{
public int I { get; }
public string S { get; }
public SomeClass(int i, string s)
{
I = i;
S = s;
}
}
}
The user is seeing an ambiguous reference exception because he has not dot-qualified his call. imho, the C# compiler should never allow this ! I;m surprised ReSharper doesn't red-line this.
Happy New Year !
«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)
modified 29-Dec-17 20:58pm.
|
|
|
|
|
See my explanation of why your code does not work in my response to Pete O'Hanlon on this thread. I think you may be surprised by what you learn.
A NameSpace with a Class (or anything else) with the same name inside it is a bad practice that will cause problems.
«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)
|
|
|
|
|
Hi,
HTML string as a JSON output.
Facing issue with the HTML string: String has HTML tags and text.
Actual string - There are HTML tags and text. In <span> tag there is id with double quotes, and there is text "since the 1500s" which also has double quotes.
<p>Lorem Ipsum is simply dummy text of the printing <span id="#" ids="#" display="inline"></span> and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever "since the 1500s".<br></p>
Expected string - All double quotes in the HTML tags should be converted into single quote but the text quotes should be as it is.
"<p>Lorem Ipsum is simply dummy text of the printing <span id='#' ids='#' display='inline'></span> and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever \"since the 1500s\".</p>"
|
|
|
|
|
Try a (complicated) regex:
public static Regex regex = new Regex(
"\"+(?=[^<]*?>)",
RegexOptions.Multiline
| RegexOptions.Singleline
| RegexOptions.CultureInvariant
| RegexOptions.Compiled
);
...
string result = regex.Replace(InputText,"'"); Get a copy of Expresso[^] - it's free, and it examines and generates Regular expressions. It helped me create and test that, then generated the C# code automatically.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Hey Guys,
Hope you guys are doing great! I have one question kind of stuck there. In the JSON File, I would like to extract the data from the node. Say like I wanted to extract the book node or value which is within goods node. Here is my JSON file.
{"store": [
{
"name": "Sunshine Department Store",
"address": "Wangfujing Street",
"goods": {
"book": [
{
"category": "Reference",
"title": "Sayings of the Century",
"author": "Nigel Rees",
"price": 8.88
},
{
"category": "Fiction",
"title": "Sword of Honour",
"author": "Evelyn Waugh",
"price": 12.66
}
],
"bicycle": {
"type": "GIANT OCR2600",
"color": "White",
"price": 276
}
}
}
]
}
Here is my code
private string ParseBookNode(JObject bookJSONFile)
{
JArray bookJson = null;
string bookFarmNode = null;
if (bookJSONFile != null && bookJSONFile["store"] != null)
{
bookJson = (JArray)bookJSONFile["store"];
bookFarmNode = bookJson[0].ToString();
if (bookJSONFile["book"] != null)
{
bookJson = (JArray)bookJSONFile["book"];
bookFarmNode = bookJson[0].ToString();
}
}
else
{
throw new Exception("Book node not found.");
}
return bookFarmNode;
}
How I can able to extract data along this lines??
if (bookJSONFile["book"] != null)
{
bookJson = (JArray)bookJSONFile["book"];
bookFarmNode = bookJson[0].ToString();
}
|
|
|
|
|
You will find that life will be much, much easier if you write container classes for these JSON objects and deserialize directly into instances of those objects. It'll also help you handle these items as strongly-typed objects in your code. I can tell you've done a bit of XML handling in the past, and it's just a different way of handling it.
public abstract class Product
{
public decimal Price { get; set; }
}
public class Book : Product
{
public string Category { get; set; }
public string Title { get; set; }
public string Author { get; set; }
}
public class Bicycle : Product
{
public string Type { get; set; }
public string Color { get; set; }
}
public class Store
{
public string Name { get; set; }
public string Address { get; set; }
public Dictionary<string,List<Product>> Goods { get; set; }
public Store()
{
Goods = new Dictionary<string,List<Product>>();
}
}
There are a couple of ways to handle the "goods" collection, but this is the easiest and should work with JSON.Net out of the box. How you obtain your object can vary a little, but parsing it directly from the original stream is preferable just for efficiency:
public Store GetStoreInventory(string fileName)
{
using(var jsonFile = new FileStream(fileName))
{
using(var reader = new StreamReader(jsonFile))
{
return JsonConvert.DeserializeObject<Store>(reader.ReadToEnd());
}
}
}
From here you can handle the data just like you would any normal .NET CLR type, i.e.
var store = GetStoreInventory(FILEPATH);
var firstBook = store.Goods["book"].FirstOrDefault();
The only "gotcha" is that the JSON.NET deserialize does not play nicely with interfaces, so use abstract classes instead (hence Product rather than IProduct).
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
Hi All,
I have just started to self learn C#, and have written my first basic application.
It is pretty simple,it has 8 text boxes that accept numerical values, which it then does some calculations on and displays 3 textbox outputs.
I worked out the calculations using Excel then translated that into C# and it all works ! as long as no one puts the wrong numbers in !
What I am trying to achieve is to validate four types of inputs:
One set of text boxes can accept whole numbers and no letters from 1 to 1000
One set of text boxes can accept whole numbers and no letters from 1 to 100
On these two types of textboxes, I have this code:
private void totalsize_TextChanged(object sender, EventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(totalsize.Text, "[^0-9]"))
{
MessageBox.Show("Please enter only full numbers i.e. 70 NOT 65.5");
totalsize.Text = totalsize.Text.Remove(totalsize.Text.Length - 1);
totalsize.Focus();
}
}
From what I understand the regex is basically checking that the first character is not non numerical, so it sort of does one part of what I needed it to do.
I then have another input that I want to be able to validate: numbers only again, but only allow a single number with a single decimal point i.e. 7.2 3.6 but not 7.22222 or 70 so anything from 1 to 9 including a single decimal point.
private void nicstrength_TextChanged(object sender, EventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(nicstrength.Text, "insert jibberish here"))
{
MessageBox.Show("Please enter only numbers.");
nicstrength.Text = nicstrength.Text.Remove(nicstrength.Text.Length - 1);
nicstrength.Focus();
}
}
The last input I want to validate will be again numbers only but from 0.n to 2.n , so 0.6 or .6 - 1.2 or 2 (2 or above will probably not ever get entered)
private void finalnicstrength_TextChanged(object sender, EventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(finalnicstrength.Text, @"^[1-9]\d*(\.\d+)?$"))
{
MessageBox.Show("Please enter only numbers.");
finalnicstrength.Text = finalnicstrength.Text.Remove(finalnicstrength.Text.Length - 1);
finalnicstrength.Focus();
}
}
I have tried zillions of combinations found on the net, plus I've used a couple of regex generators (frustratingly, some say a regex works and some say it doesn't - but none work when I put them into my code !)
I've learnt that I either need to put an @ in front of it, or use double \\ or whatever for C# to know what it is, but i'm just really struggling with this.
I am dyslexic (not looking for sympathy) so looking at regex makes my head explode !
Please can someone help me with the last two types at the very least, I know the top two are not 100% correct, but they at least stop letters and decimal points being entered.
Many thanks for reading, and even more for helping me !
Damian
|
|
|
|
|
Basically, don't use a regex!
The simplest solution is this:
int value;
if (!(int.TryParse(myTextBox.Text, out value) && value >= 1 && value <= 100))
{
MessageBox.Show("Please enter a number between 1 and 100");
...
return;
} It's clearer, it's much simpler to maintain, and it gives you the value as a number for when you need it later.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
This also has the benefit of being faster than a regex. Try to save regex for things where absolutely nothing else will do like dealing with string lookups in long documents and protocol parsing; regex are not as fast as you might think.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
Nathan Minier wrote: regex are not as fast as you might think
I know! Counting Lines in a String[^]
It compares the different ways to do it: brute force, regex, Linq, ... interesting results.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I've done a few tests for a BSON parser that I've been working on, and found that regex is literally 100x slower than a String.Split implementation with count checks (for my use case anyway). I was floored.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
It surprised me that both Linq and Regex were so slow: Split is not nice either due to the number of object allocations you need but I was expecting that - allocation is always a time consuming operation.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Yeah, but this is C#. I'm not going to build a stream buffer with segment comparator in C#; that's an unmanaged C/++ project
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
Thank Nathan,
But I don't think performance is going to be an issue ..
It's only a 260~ line app with 3 calculations to work out the percentages of 3 ingredients
Cheers
Damian
|
|
|
|
|
Performance is always an issue: code never stays the same, and if you write something inefficiently, it will still be inefficient when it's reused (or repurposed) and then it's harder to work out why your app is slow.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
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
|
|
|
|
|