0

I have a list box that contains the ID number and model of a number of cars, taken from an access table. I have some text boxes that will be filled with the data from that table when a car is selected from the list box. To get the id number of the selected car, I'm using this code:

int idNum = listBox1.SelectedItem.ToString()[0];

Which should get the first character in the item string (it's ID number). When I select the first item in the list, what I am instead getting is 49. My first thought was that I wasn't casting it to an int, so maybe the 49 represents some character code for the number, however

Convert.ToInt16(listBox1.SelectedItem.ToString()[0])

Returns the exact same number. The second item is 50, and so on and so forth.

I want to be changing how I get the ID number from this char conversion anyway, as it's just occurred to me that once I hit 10 cars it won't work, but why am I getting such a large, consistently offset, and (perhaps most bafflingly of all) multi-digit number from a c# equivalent of java's charAt[0]?

The specific error I've been getting is that there is no row at position 49, which pops up when I try to get the value of mydataset.Tables["mytable"].Rows[idNum]["CarID"].ToString();. Now, I can see a few things that could be causing this issue, I have absolutely know idea if Rows[idNum]["CarID"] is the correct syntax, and was very surprised to see that my guess worked, but it's still a very weird problem.

Space Ostrich
  • 413
  • 3
  • 5
  • 13

3 Answers3

1

You need to get the numeric value for Char:

int idNum = (int)Char.GetNumericValue(listBox1.SelectedItem.ToString()[0]);

While int idNum = listBox1.SelectedItem.ToString()[0]); return the ASCII of Character '1' (example) which is 49.

This is the actual code from Microsoft for Convert.ToInt16:

public static short ToInt16(char value) 
{
    // Some validations
    return (short)value;
}

Convert.ToInt16 for a char does an Explicit conversion, which gets the ASCII for that Character Value.

For Handling Multiple Digits:

string str = "37abcdef";
string myStrNumber  = Regex.Match(str, @"\d+").Value;

int idNum2;

if (myStrNumber.Length > 0)
    idNum2 = Convert.ToInt32(myStrNumber);
else
{
    // Handle Error
}

Or Without using Regex :

string str = "37abcdef";
string myStrNumber = "";

for(int i = 0; i < str.Length; i++)
{
    if (Char.IsNumber(str[i]))
        myStrNumber += str[i];
}

int idNum2;

if (myStrNumber.Length > 0)
    idNum2 = Convert.ToInt32(myStrNumber);
else
{
    // Handle Error
}
Zein Makki
  • 29,485
  • 6
  • 52
  • 63
  • I tried that out and it worked. I wound up using `int idNum = (int)Char.GetNumericValue(listBox1.SelectedItem.ToString()[0]) - 1;`, though I am confused as to why this works but `Convert.ToInt16` does not. Or is that just converting the ASCII value of the character to an int/not converting anything as ASCII values are already ints? – Space Ostrich Jun 01 '16 at 05:31
  • 1
    @SpaceOstrich I think when you use the `Convert` instead of parsing - `Convert` probably just does a cast in this case whereas a `Int16.Parse` will actually parse the string/char and return the numerical value. – Abbath Jun 01 '16 at 05:36
  • 1
    @SpaceOstrich check the edited answer, i added the actual code from microsoft. – Zein Makki Jun 01 '16 at 05:38
  • thanks for that, with the issue identified, I made some changes and now use `split` to get the id part of the string. I'll be throwing up my own answer with that working code for future reference. I'll mark yours as the correct answer, I'd just like the solution up here as well. – Space Ostrich Jun 01 '16 at 05:40
  • 1
    @SpaceOstrich Check my edited answer for a case where you want to handle multiple digits. – Zein Makki Jun 01 '16 at 05:49
1

Try this

int idNum = Convert.ToInt16(listBox1.SelectedItem.ToString()[0].ToString())

because

listBox1.SelectedItem.ToString()[0] return Char. If you convert a Char type data to Integer it will return ASCII of Char. So Convert it into string before converting to Integer ( listBox1.SelectedItem.ToString()[0].ToString() ).

Manu Varghese
  • 791
  • 8
  • 25
0

user3185569 identified the problem, but I'll put up the solution I ended up using for future reference. The int idNum = listBox1.SelectedItem.ToString()[0]); line was getting the ASCII for the character, 49 for 1, 50 for 2, etc. This can be solved by using (int)Char.GetNumericValue(listBox1.SelectedItem.ToString()[0]) -1;.

(int)Char.GetNumericValue gets the actual number value of that character, rather than the ASCII value. The - 1 is to account for the car ID's starting from 1, but the table indexes start from 0.

This still leaves the issue of digits, if the first character of the string is being used to get the ID number, as soon as there are more than 9 cars, the code won't work. The strings are written in the listbox as "[idNum]: [carName]". For example: 1: Astra. To get the ID number I used Split(':')[0], which splits the string into an array of substrings, splitting at each : character.

The working line of code is:

int idNum = Convert.ToInt16(listBox1.SelectedItem.ToString().Split(':')[0]) - 1; 
Space Ostrich
  • 413
  • 3
  • 5
  • 13