I am learning C# (in Visual Studio Express 2013 for Windows Desktop) by converting a simple Windows Form application I previously wrote in Visual Basic.
The following code sends a text box entry and two integers to a method that returns a boolean, but throws an exception at runtime whenever the text box doesn't contain an integer (e.g 155 is OK, but 155.67 isn't).
if (!(rangeOK(int.Parse(cmTextBox.Text), 50, 250))) return false;
I've tried using TryParse to resolve this, but despite trying lots of online tips (and others' questions in here) I haven't been able to understand how I should do it.
If it helps the original VB code was:
If Not (rangeOK(Val(cmTextBox.Text), 50, 250)) Then Return False
Many thanks
Rob
This is how you use TryParse:
int result; // does not need to be initialized
if (int.TryParse(cmTextBox.Text, out result))
{
if (!(rangeOK(result, 50, 250)))
return false;
// todo
} else
{
// process error
}
More information here:
http://msdn.microsoft.com/en-us/library/f02979c7%28v=vs.110%29.aspx
Good luck with it!
UPDATE
You can do the same with double.TryParse of coure, if you want to work with non integer numbers. More information here:
http://msdn.microsoft.com/en-us/library/994c0zb1%28v=vs.110%29.aspx
Related
This coding was recently upgraded from C#.Net 2008 to C#.Net 2012. The value of this cell in this DataGridView = 4 but an exception is thrown every time my program arrives at this line. What am I missing here ?
if (((int)dgQueue.SelectedRows[0].Cells["StatusKey"].Value != 1 && isRequestCheck))
I'm receiving an InvalidCastException with a detail explanation of Specified cast is not valid...
As mentioned dgQueue.SelectedRows[0].Cells["StatusKey"].Value should work with specified cast. Try to use below format and it should work, if the datatype of the value is equal to expected.
If the value expecting is 4 then the line should be
int i =(int)dgQueue.SelectedRows[0].Cells["StatusKey"].Value.ToString().Trim();
int i =Convert.ToInt32(dgQueue.SelectedRows[0].Cells["StatusKey"].Value.ToString().Trim());
One second. Prior to the answers given (and thank you for those), I was able to make this work
if ((Convert.ToInt32(dgQueue.SelectedRows[0].Cells["StatusKey"].Value) != 1 && isRequestCheck))
Has (int) conversion been deprecated in 2012 ? Or, could there be a value other than an integer is the "StatusKey" cell collection (perhaps a null value) ? I'm trying to understand why this coding worked just fine in 2008 and now in 2012, it doesn't. Any ideas ??? I ask because this coding technique is all over this application and I'm thinking to change all my lines to the strategy above...
Ok, so to start off, this is my first time working with C#, and the top it off I am attempting to work with it in a report editor for MYOBs AEPM software, which doesn't exactly give me a lot of info or flexibility. What I have been able to work out is that it uses some version of Data Dynamics Active Reports, but not sure which one. I also cannot seem to figure out what naming they have used for much of the report. Anyway, back to the main issue.
I am needing to add some calculations to the report that the visual editor wont allow me to do(it is restricted to Count, Sum, Min, Max, Avg, Var, so not really helpful). Now the calculations are pretty simple(One is a total x .7, and the other being the result of the first x 74 but this value might be changed in the future). Figured the best way would be to just have 2 text boxes with a value in each of them of "0", and then just once the main report is pretty much done run the calculations and replace the values of the two text boxes. So I made the text boxes in the appropriate section and labelled them CalcTotal1 and CalcTotal2.
Now in the editor it allows me to select the object and an event to trigger it, so selected ReportFooter as the object and AfterPrint as the event. I then just put in a line to chance the CalcTotal1 value and tried to generate the report resulting in the following error:
Error Message: Report Script Compile Error on line 8 Error = The name 'CalcTotal1' does not exist in the current context
public void ReportFooter_AfterPrint()
{
CalcTotal1.Text = "Hello";
}
I have tried looking at the documentation for Active Reports but I am not having much luck, so any ideas would be incredibly welcome.
just add "this" word in the code like
this.CalcTotal1.Test = "Hello";
http://helpcentral.componentone.com/nethelp/AR8Help/AR8_HelpOnlineEN/Scripts.html provides some more tips.
The MYOB AE PM feature referred to is called Smart Reports.
I was able to replicate the error and consequently resolved the problem by using the following syntax:
((TextBox)rpt.Sections["Detail"].Controls["TextBox2"]).Text= "$2000.00";
eg:
public void Detail_AfterPrint()
{
((TextBox)rpt.Sections["Detail"].Controls["TextBox2"]).Text= "$2000.00";
}
this is really my first time asking here, but I'm facing a problem which I'm sure of I'm missing something simple.
I wrote a C# class library with a function that returns a List>. The function itself works fine if used from a console application that I created to test the DLL.
The ending part of the function is:
/* Sorto i risultati in base al ranking */
List<KeyValuePair<string, double>> SortedList = new List<KeyValuePair<string, double>>(matchIndexList_rank);
SortedList.Sort(delegate(KeyValuePair<string, double> firstPair,
KeyValuePair<string, double> secondPair)
{
return (-1) * firstPair.Value.CompareTo(secondPair.Value);
}
);
stopWatch.Stop();
response.success = true;
response.executionTime = stopWatch.ElapsedMilliseconds;
response.resultListKVPStrDoub = SortedList;
return response;
Here for example the double part of the first value in the list is 15.5796761265999 (sorry cannot include pictures yet!)
The problem rises if I include the DLL in a ASP.NET MVC Application that uses the function. In this case the double part of the List> is returned without the decimal part.
The corresponding value to the one presented above is returned as 155796761265999.0
Here is a little bit of code where i get the wrong value returned:
searchEngine.Core.search search = new searchEngine.Core.search(HttpContext.Current.Server.MapPath("~/index_" + oIdentity.comapanyId.ToString()));
searchEngine.Core.genericResponse response = search.doSearch(searchStr);
double maxScore = response.resultListKVPStrDoub.Count > 0 ? response.resultListKVPStrDoub[0].Value : 1;
In example maxScore get the 155796761265999.0 value, but also every other value in the List suffers the same problem.
If I inspect the variables from both sides Visual Studio 2013 states that the type is indeed a double.
Both projects are developed on the same machine which also is my test environment. I use .Net Framework 4.0 on both projects and all build parameters seems to be equal on both projects.
I'm sure I'm missing something simple, but just can't get.
I'd appreciate any help.
Thanks
Lorenzo
Hi, problem solved ! (sorry but I can't yet answer by own question before 8 hours from posting)
Thanks to Radu Pascal that put me on the right way: normally I always add a class library to a solution to debug it, but in this case I had it developed for another project and it was working fine so I ignored the obviuos.
Thanks to Marc Gravell, he spotted the problem: even if I forgot it at the base of my search engine there is a file based index. There is where i reed my values from text and there is where I do the reading wrong.
The real mystery is that the same DLL used in the console application used for testing and even on another ASP.NET MVC on the same machine works fine. I solved using double.parse instead of Convert.ToDouble and imposing an invariant culture.
idfDict[idItem] = double.Parse(s.Split('|')[1], System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.NumberFormatInfo.InvariantInfo);
Thanks to all!
Lorenzo
Hi, problem solved !
Thanks to Radu Pascal that put me on the right way: normally I always add a class library to a solution to debug it, but in this case I had it developed for another project and it was working fine so I ignored the obviuos.
Thanks to Marc Gravell, he spotted the problem: even if I forgot it at the base of my search engine there is a file based index. There is where i reed my values from text and there is where I do the reading wrong.
The real mystery is that the same DLL used in the console application used for testing and even on another ASP.NET MVC on the same machine works fine. I solved using double.parse instead of Convert.ToDouble and imposing an invariant culture.
idfDict[idItem] = double.Parse(s.Split('|')[1], System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.NumberFormatInfo.InvariantInfo);
Thanks to all!
Lorenzo
I have a new laptop at work and code that worked earlier in the week does not work today.
The code that worked before is, simplified:
while (dr.Read())
{
int i = int.Parse(dr.GetString(1))
}
Now it fails when the database value is 0. Sometimes, but not reliably, this will work instead:
while (dr.Read())
{
int i = Convert.ToInt32(dr["FieldName"]))
}
Am I missing something stupid?
Oddly enough, ReSharper is also having tons of weird errors with the same error message that I am getting with the above code: "input string was not in the correct format." (Starts before I even load a project.)
Any ideas? Anyone having any SP issues? I did try to make sure all my SPs were up-to-date when I got the machine.
EDIT: I understand how to use Try.Parse and error-handling. The code here is simplified. I am reading test cases from a database table. This column has only 0, 1, and 2 values. I have confirmed that. I broke this down putting the database field into a string variable s and then trying int.Parse(s). The code worked earlier this week and the database has not changed. The only thing that has changed is my environment.
To completely simplify the problem, this line of code throws an exception ("input string was not in the correct format"):
int.Parse("0");
EDIT: Thanks to everyone for helping me resolve this issue! The solution was forcing a reset of my language settings.
A possible explanation:
Basically, the problem was the
sPositiveSign value under
HKEY_CURRENT_USER\Control
Panel\International being set to 0,
which means the positive sign is '0'.
Thus, while parsing the "positive sign
0" is being cut off and then the rest
of the string ("") is parsed as a
number, which doesn't work of course.
This also explains why int.Parse("00")
wasn't a problem. Although you can't
set the positive sign to '0' through
the Control Panel, it's still possible
to do it through the registry, causing
problems. No idea how the computer of
the user in the post ended up with
this wrong setting...
Better yet, what is the output of this on your machine:
Console.WriteLine(System.Globalization.NumberFormatInfo.GetInstance(null).PositiveSign);
I'm willing to bet yours prints out a 0... when mine prints out a + sign.
I suggest checking your Control Panel > Regional and Language Options settings... if they appear normal, try changing them to something else than back to whatever language you're using (I'm assuming English).
I think it's generally not considered a good idea to call Convert.ToInt32 for the value reading out of database, what about the value is null, what about the value cannot be parsed. Do you have any exception handling code here.
Make sure the value is not null.
Check the value can be parsed before call Int32.Parse. Consider Int32.TryParse.
consider use a nullable type like int? in this case.
HTH.
Edit:
#Mike's response made me think that is extremely odd behavior and a simple google search yielded this result: int.Parse weird behavior
An empty string would also cause this issue.
You could check for dbnull before parsing, also it is good to validate parsed data.
You could use a default value and TryParse..
int i = -1;
if(!int.TryParse(dr["MyColumn"] as string, out i))
//Uh Oh!
Edit:
I posted this as a comment in #Chris' answer, but if the sql datatype is int then why not just use the GetInt32 method on the DataReater instead of retrieving it as a string and manual parsing it out?
Are you sure it's "0" and not "null"? What exception do you get?
EDIT:
Just out of curiosity, if it is really faulting on int.Parse("0"), can you try int.Parse("0", CultureInfo.InvariantCulture);?
Otherwise, post your query. Any joins?
you should check dr["FieldName"] != DBNull.Value and you should use TryParse if it passes the DBNull test...
if ( dr["FieldName"] != DBNull.Value )
{
int val = 0;
if ( int.TryParse( dr["FieldName"], out val ) )
{
i = val;
}
else
{
i = 0; // or some default value
}
}
I have seen this issue crop up with .NET Double class, parsing from string "0" as well.
Here's the really wacky part: you can get past the issue by using a different user account to run the program, and sometimes if you destroy and re-create the current user account on the machine, it will run fine.
I have yet to track this down, but you might get past it this way at least.
This is way out of left field, but check your localization settings. I had a number of "input string was not in a correct format" when I moved a web site to a Canadian server. The problem was in a DateTime.Parse method, and was fixed by setting the culture to "en-US".
Yes, your situation is different — but hey, you never know.
are you checking for null ?
if(!dr.IsNull("FieldName")){
int i = Convert.ToInt32(dr["FieldName"]))
}
I'm messing around with some windows functions using p/invoke. Occasionally, I get an error code that is not ERROR_SUCCESS (such an odd name).
Is there a way to look these up within the program? Forexample, if I get error 1017. Can I tell the user
The system has attempted to load or
restore a file into the registry, but
the specified file is not in a
registry file format.
(ERROR_NOT_REGISTRY_FILE: 0x3F9)
Instead of
Error Code: 1017
I'm not sure if there's a niifty .NET wrapper, but you could call the FormatMessage API using P/Invoke.
See this answer for how it would normally be called from native code. Though the question refers to grabbing error codes from HRESULTs, the answer also applies for retreiving codes from the regular OS error codes coming from GetLastError/GetLastWin32Error).
EDIT: Thanks Malfist for pointing me to pinvoke.net, which includes alternative, managed API:
using System.ComponentModel;
string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
Console.WriteLine(errorMessage);
You could take the defines from winerror.h at Rensselaer Polytechnic Institute, and put them into an Enum:
public enum Win32ErrorCode : long
{
ERROR_SUCCESS = 0L,
NO_ERROR = 0L,
ERROR_INVALID_FUNCTION = 1L,
ERROR_FILE_NOT_FOUND = 2L,
ERROR_PATH_NOT_FOUND = 3L,
ERROR_TOO_MANY_OPEN_FILES = 4L,
ERROR_ACCESS_DENIED = 5L,
etc.
}
Then if your error code is in a variable error_code you would use :
Enum.GetName(typeof(Win32ErrorCode), error_code);
I landed on this page while in search of a managed alternative to calling FormatMessage through P/Invoke.
As others have said, there is no way to get those capitalized, underscored names, short of looking them up in winerror.h, which I have seen reproduced online in various places where I landed in the course of searching for information about resolving specific status codes. A quick Google search, for winerror.h, itself, uncovered a page, at Rensselaer Polytechnic Instutute, where someone has helpfully extracted the #define statements from it.
Looking at it gave me an idea; I think there may be a way to get there, working from the source code of winerror.h, which I have, as part of the Windows Platform SDK that ships with every recent version of Microsoft Visual Studio.
Right now, I am in the middle of sorting out a pressing issue in the .NET assembly that brought me to this page. Then, I'll see what I can cobble together; this kind of challenge is right up my alley, and somebody threw down a gauntlet.
Yes there's a function that does that but I don't remember what it is. In the mean time, you can use the error lookup tool (Tools->Error Lookup) to see what a particular code means from within Visual Studio.