|
Hi! Sorry for the delay in responding, I had to collect my wife for work, feed her lunch, that kind of thing...
You aren't far off what you want to do, you have just got bogged down in "that works so I'll keep it" syndrome! We all do that, so don't feel bad!
I have modified your code a fair amount, and will explain why as we go through:
Double xVal = 0;
foreach (DataGridViewRow row in d_Endpost.Rows)
{
double postSpacing = 0.0;
double postSpacingMetric = 0.0;
string userEntry = (string)row.Cells["EPSpacing"].Value;
if (!string.IsNullOrEmpty(userEntry))
{
if (Double.TryParse(userEntry, out postSpacing))
{
postSpacingMetric = Imperial2Metric(postSpacing);
}
else
{
MessageBox.Show("Invalid entry (" + userEntry + ") please enter the post spacing in inches and try again");
return;
}
xVal += postSpacingMetric;
Console.WriteLine(xVal);
}
}
Firstly, I have removed the outer loop - as you have realised, you only need the one and in this case the foreach makes it all a bit more readable. Generally, try to avoid for loops when you can use foreach and don't need to know how many elements you are dealing with.
Next, I specifically get the element value into a string - you don't need to do this, but it both makes it more obvious and ties the error message to it better later. Because we know that a DataGridViewRow.Value property will (in this case) always be a string, we can cast it, with no need for a conversion.
Then, check it isn't empty! If it is, and we don't check, then we will get a null reference exception.
Ok so far, try and parse it. TryParse works like Parse, but instead of throwing an exception if the user types in his name instead of the distance, it returns will a true or false to say the conversion worked. If it fails, tell the user what he did wrong!
It is always worth checking user input - if you don't then a simple mistake can cause your program to fail. Check it, and handle it nicely!
Include the current metric value in the running total.
Display the total so far with Console.WriteLine - this is where you would do whatever you need to with the values as they are being generated.
Why do I not check the first one to start the running total? Why bother? Because I initialise the running total to 0 when I declare it, the first element output will be the first value the user enters. If I don't need to create a special case, I won't bother!
Try running this through the debugger - it is well worth getting used to it, you are going to spend a lot of time looking at your code through debug screens!
Hope that all makes sense!
[edit] included the word "don't" in the phrase "so don't feel bad" - Oops![/edit]If Barbie is so popular, why do you have to buy her friends?
Eagles may soar, but weasels don't get sucked into jet engines.
If at first you don't succeed, destroy all evidence that you tried.
|
|
|
|
|
I think that all makes sense. I was wondering how to do a check if the user used a value or not.
It kinda works now.
If I say put 3 spaces at 120", it now puts all of the items at 360". Instead of 1 at 120" 1 at 240" and 1 at 360".
I greatly appreciate your help!
|
|
|
|
|
Post teh code you are using - I'd guess it's a typo, or you are using the values after the loop - when they are allready added together... If Barbie is so popular, why do you have to buy her friends?
Eagles may soar, but weasels don't get sucked into jet engines.
If at first you don't succeed, destroy all evidence that you tried.
|
|
|
|
|
After looking at it again I was ending my foreach statement to early.
I don't know why I didn't put the rest of the code in there.
Now it works great! I thank you for all of your help..
|
|
|
|
|
You are welcome! If Barbie is so popular, why do you have to buy her friends?
Eagles may soar, but weasels don't get sucked into jet engines.
If at first you don't succeed, destroy all evidence that you tried.
|
|
|
|
|
|
OK, rules for good code:
1) Don't use "#region" to break up your code, use it to group together similar items - consturctors, event handlers, public methods, private methods, and so on. If you want to show where you are handling comething, then extract it into a method, and give the method a sensible name "SingleC" and "DoubleC" for example. You can then comment these using "///" and intellisense will pick up and help you out. It makes the flow of control easier to spot. VS can extract code as a method, just highlight it and right click - "Refactor", "Extract Method"
2) Use indenting properly! VS indents things really nicely, and make it so much more obvious what it going on - I had to faff around a bit to get it like this (since I don't have and dont want) your class definitions but then VS indented everything really nicely.
3) Be consistant in indenting: one space, two space, back a bit - it really doesn't help you see what is going on. VS has loads of options for this: Indent braces to match content, number of character to indent, newlines, opening brace on same line, etc. Find a style you like, and stick with it. I prefer braces on new lines, indent three characters, indent braces to match content - but that is me, and there are enough arguments about that allready!
4) Don't use comments to explain what the code does - explain why the code is doing it. "This Sets If its a Single CEE or Double CEE" followed by a test saying "if (DBLCee == "False")" is useless - why is it important to know if it is single or double cee? I have no idea, and the comment does not help me at all. (P.S. I don't actually need to know, but someone who works on your code might).
double xVal = 0;
foreach (DataGridViewRow row in d_Endpost.Rows)
{
double postSpacing = 0.0;
double postSpacingMetric = 0.0;
string userEntry = (string)row.Cells["EPSpacing"].Value;
if (!string.IsNullOrEmpty(userEntry))
{
if (Double.TryParse(userEntry, out postSpacing))
{
postSpacingMetric = I2M(postSpacing);
}
else
{
MessageBox.Show("Invalid entry (" + userEntry + ") please enter the post spacing in inches and try again");
return;
}
xVal += postSpacingMetric;
Console.WriteLine(xVal);
}
string PostType = row.Cells["EndPostType"].FormattedValue.ToString();
string DBLCee = row.Cells["DBLCee"].FormattedValue.ToString();
if (DBLCee == "False")
{
SingleCee(Distance2Points, xVal, PostType);
}
else
{
DoubleCee(Distance2Points, xVal, PostType);
}
}
From this you can see a couple of things straight away:
1) All your processing code is outside the check to see if there is any data to process!
2) You have lest the Console.WriteLine in, when it serves no purpose now.
And the mthods became:
private void DoubleCee(double Distance2Points, double xVal, string PostType)
{
if (xVal < Distance2Points / 2)
{
Beam EndPost = new Beam();
EndPost.StartPoint = new T3D.Point(xVal, 0, 0);
EndPost.EndPoint = new T3D.Point(xVal, 0, (EaveHt - (PurlinSlope + I2M(1.5))) + (xVal * Math.Tan(AngleRadians)));
EndPost.Material.MaterialString = "55";
EndPost.Name = "Endpost";
EndPost.Profile.ProfileString = PostType.ToString();
EndPost.Position.Depth = Position.DepthEnum.BEHIND;
EndPost.Position.Plane = Position.PlaneEnum.LEFT;
EndPost.Position.Rotation = Position.RotationEnum.FRONT;
EndPost.Class = "3";
EndPost.Insert();
Beam EndPostR = new Beam();
EndPostR.StartPoint = new T3D.Point(xVal, 0, (EaveHt - (PurlinSlope + I2M(1.5))) + (xVal * Math.Tan(AngleRadians)));
EndPostR.EndPoint = new T3D.Point(xVal, 0, 0);
EndPostR.Material.MaterialString = "55";
EndPostR.Name = "Endpost";
EndPostR.Profile.ProfileString = PostType.ToString();
EndPostR.Position.Depth = Position.DepthEnum.FRONT;
EndPostR.Position.Plane = Position.PlaneEnum.LEFT;
EndPostR.Position.Rotation = Position.RotationEnum.FRONT;
EndPostR.Class = "3";
EndPostR.Insert();
}
else
{
Beam EndPost = new Beam();
EndPost.StartPoint = new T3D.Point(xVal, 0, 0);
EndPost.EndPoint = new T3D.Point(xVal, 0, (EaveHt - (PurlinSlope + I2M(1.5))) + ((Distance2Points - xVal) * Math.Tan(AngleRadians)));
EndPost.Material.MaterialString = "55";
EndPost.Name = "Endpost";
EndPost.Profile.ProfileString = PostType.ToString();
EndPost.Position.Depth = Position.DepthEnum.BEHIND;
EndPost.Position.Plane = Position.PlaneEnum.LEFT;
EndPost.Position.Rotation = Position.RotationEnum.BACK;
EndPost.Class = "3";
EndPost.Insert();
Beam EndPostR = new Beam();
EndPostR.StartPoint = new T3D.Point(xVal, 0, (EaveHt - (PurlinSlope + I2M(1.5))) + ((Distance2Points - xVal) * Math.Tan(AngleRadians)));
EndPostR.EndPoint = new T3D.Point(xVal, 0, 0);
EndPostR.Material.MaterialString = "55";
EndPostR.Name = "EndPostR";
EndPostR.Profile.ProfileString = PostType.ToString();
EndPostR.Position.Depth = Position.DepthEnum.FRONT;
EndPostR.Position.Plane = Position.PlaneEnum.LEFT;
EndPostR.Position.Rotation = Position.RotationEnum.BACK;
EndPostR.Class = "3";
EndPostR.Insert();
}
}
private void SingleCee(double Distance2Points, double xVal, string PostType)
{
if (xVal < Distance2Points / 2)
{
Beam EndPost = new Beam();
EndPost.StartPoint = new T3D.Point(xVal, 0, 0);
EndPost.EndPoint = new T3D.Point(xVal, 0, (EaveHt - (PurlinSlope + I2M(1.5))) + (xVal * Math.Tan(AngleRadians)));
EndPost.Material.MaterialString = "55";
EndPost.Name = "Endpost";
EndPost.Profile.ProfileString = PostType.ToString();
EndPost.Position.Depth = Position.DepthEnum.MIDDLE;
EndPost.Position.Plane = Position.PlaneEnum.LEFT;
EndPost.Position.Rotation = Position.RotationEnum.FRONT;
EndPost.Class = "3";
EndPost.Insert();
}
else
{
Beam EndPost = new Beam();
EndPost.StartPoint = new T3D.Point(xVal, 0, 0);
EndPost.EndPoint = new T3D.Point(xVal, 0, (EaveHt - (PurlinSlope + I2M(1.5))) + ((Distance2Points - xVal) * Math.Tan(AngleRadians)));
EndPost.Material.MaterialString = "55";
EndPost.Name = "Endpost";
EndPost.Profile.ProfileString = PostType.ToString();
EndPost.Position.Depth = Position.DepthEnum.BEHIND;
EndPost.Position.Plane = Position.PlaneEnum.LEFT;
EndPost.Position.Rotation = Position.RotationEnum.BACK;
EndPost.Class = "3";
EndPost.Insert();
}
}
(I will leave it to you to comment them since I don't know that much about roofing houses!)If Barbie is so popular, why do you have to buy her friends?
Eagles may soar, but weasels don't get sucked into jet engines.
If at first you don't succeed, destroy all evidence that you tried.
|
|
|
|
|
|
miggs70 wrote: I wasn't aware that I could separate things out with privates
They are called methods: private is a keyword that can go before the return type to tell the compiler that it should not be visible outside the class.
If you are trying to learn C# by looking at samples, you will take forever, and will have to work very hard. You will find it easier if you try a more structured method, such as a book. Have a look here: C# Yellow Book[^] it is the book they give first year students at Hull University and it's both not a bad start and free.
Do you have a copy of Visual Studio yet? If not, then Microsoft will give you a copy of the Express edition (which handles most things, and is well up to learning the language). See Here[^] for a copy. Warning - it's quite big!
And of course - CodeProject is more than willing to help!If Barbie is so popular, why do you have to buy her friends?
Eagles may soar, but weasels don't get sucked into jet engines.
If at first you don't succeed, destroy all evidence that you tried.
|
|
|
|
|
can any 1 send me the link that finds overlapping area of n rectangles
|
|
|
|
|
How can i change resource file that i use it in my project at runtime !
or
How to change Resource file Dynamically ?!
|
|
|
|
|
See the MSDN[^] pages on resource files.
Hint: try researching with Google/MSDN/CodeProject articles first.MVP 2010 - are they mad?
|
|
|
|
|
how to have :
System.ComponentModel.ComponentResourceManager res = new ComponentResourceManager(typeof("<code>C:\Resource.resx</code>"));
|
|
|
|
|
I don't think you can get what you have coded above; see here[^] for details. MVP 2010 - are they mad?
|
|
|
|
|
I am developing an application in c# , but the default window style on vista does not fit my requirement in term of look .
I want to have the application style like the default style in MFC application .
I am really concerned about the menustrip which I would like to be like the one in VLC player or any default MCF application
please How can I do it in c#. look around but nothing about it .
Application.EnableVisualStyle(); does not work
|
|
|
|
|
Is it ok in .Net 3.5 to change a property within a foreach loop? Does it still run the risk of producing unpredictable results? Also, will the potential results be noticeable or might it cause some type of slow, inconspicuous but nonetheless catastrophic error.
For example:
foreach(Employee janitor in EmployeesWithPayIncrease)
{
janitor.Salary += 5000;
}
Thanks for any help or information you can provide.
|
|
|
|
|
It is fine to change a property; the only thing you can't do is change the loop variable or the list itself.
So
foreach(Employee janitor in EmployeesWithPayIncrease)
{
janitor.Salary += 5000;
} is fine, but
foreach(Employee janitor in EmployeesWithPayIncrease)
{
janitor = new Employee();
} or
foreach(Employee janitor in EmployeesWithPayIncrease)
{
EmployeesWithPayIncrease.Remove(janitor);
} are not, as it would mean it would compromise the enumeration.If Barbie is so popular, why do you have to buy her friends?
Eagles may soar, but weasels don't get sucked into jet engines.
If at first you don't succeed, destroy all evidence that you tried.
|
|
|
|
|
I can think of ways to make the first piece of code fail as well
|
|
|
|
|
So can I! But I figure that if he is asking a basic (sensible, but basic) question like that, I didn't want to confuse him with custom comparisons, etc. I found it refreshing to be politely asked a sensible question If Barbie is so popular, why do you have to buy her friends?
Eagles may soar, but weasels don't get sucked into jet engines.
If at first you don't succeed, destroy all evidence that you tried.
|
|
|
|
|
True
I can also think of ways to make the other two pieces* of code work without (changing them, of course)
But it's not like that's going to happen in the real world a lot either
edit *: well ok only the last one, unless I'm allowed to cheat
|
|
|
|
|
Thanks for the information. I appreciate the answer.
However, I am curious: how could you make the first piece of code fail? Also, my code will work without unintended consequences, right?
|
|
|
|
|
BlitzPackage wrote: how could you make the first piece of code fail
The setter of that property could be changing the collection in some way
BlitzPackage wrote: Also, my code will work without unintended consequences, right?
Well that depends on what the property is doing..
|
|
|
|
|
You can't modify an object in a foreach loop like that. You have to loop differently (for , while , etc).45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
Yes you can - provided the property you modify does not alter the comparison, or add / remove items from the collection. Increasing the salary would not be a problem. If Barbie is so popular, why do you have to buy her friends?
Eagles may soar, but weasels don't get sucked into jet engines.
If at first you don't succeed, destroy all evidence that you tried.
|
|
|
|
|
When a foreach is applied to a collection, C# will have the collection return an enumerator (I believe by calling a method, GetEnumerator). With the built in .Net types, those enumerators have logic in them that throw an exception if they detect that the list has been changed since the enumerator was created. They do this by taking a snaphot of the version number stored in the collection. Whenever a collection is modified, .Net increments this version number. And whenever an element is gotten from the enumerator, it checks it's version number against the collection it was created from.
The version number is only incremented for operations that change the structure of the list (reordering items, item removal, item additions, assigning items, and so on), not ones that change simple attributes of the list.
Also, most programmers are not aware that this version incrementing and checking must be done, so many custom collections will not throw an exception when the collection was modified in a foreach. For example, you could yourself create a custom collection that doesn't check if the collection was modified. Then no exception would be thrown when you modify the collection (add items, delete them, etc).
Whether or not modifying the collection during a foreach would cause an error (note that I didn't say "exception", I said "error") entirely depends on the collection.
|
|
|
|
|