4

I have a combobox in winforms that has the following items:

 15 min
 30 min
 1 hr
 1 hr 30 min
 2 hr
 2 hr 30 min
etc . . 

Here is the screenshot of the winforms combobox Collection Items editor

enter image description here

and i need to parse that string and return an integer which represents the number of minutes. I wanted to see the most elegant way of doing that (right now i am splitting by space and then counting array length and it feels a bit wrong.

So parsing

2h 30 mins

would return 150

leora
  • 188,729
  • 360
  • 878
  • 1,366
  • 8
    Why don't you store the number of minutes along each dropdown entry? – dtb Jun 26 '13 at 17:37
  • what do you mean by number of minutes?are you counting or adding..be clear with your question... – Anirudha Jun 26 '13 at 17:40
  • Which technology? (asp.net, forms, wpf etc) or doesn't it matter? – Peter Rasmussen Jun 26 '13 at 17:41
  • 1
    When using a dropdownlist one thing is the text, and something else is the value. Have the value be the minutes. Then get the value of the Selected item. – Dzyann Jun 26 '13 at 17:46
  • @Xeano - its winforms but i don't see why that matters – leora Jun 26 '13 at 17:52
  • @Dzyann - I added a screenshot, i don't see a place to put values on a combobox – leora Jun 26 '13 at 17:52
  • @Anirudh - basically adding 60 * hours + mins and returning a number – leora Jun 26 '13 at 17:54
  • @leora I saw the question when you said it was a dropdown :) – Dzyann Jun 26 '13 at 18:25
  • @leora check out this solution: http://stackoverflow.com/questions/3063320/combobox-adding-text-and-value-to-an-item-no-binding-source You could have your minutes in the values and then show the string in whatever way you want. – Dzyann Jun 26 '13 at 18:42

3 Answers3

4

Since you said this is a combobox, then you will have to parse the value. Your user might enter a value of their own as well.

var formats = new[] {"h' hr'", "m' min'", "h' hr 'm' min'"};

TimeSpan ts;
if (!TimeSpan.TryParseExact(value, formats, null, out ts))
{
    // raise a validation message to your user.
}

// you said you wanted an integer number of minutes.
var minutes = (int) ts.TotalMinutes;

You can pass any of the strings you showed in your example as the value.

However, be aware that due to how TimeSpan works, you cannot parse more than 23 hours or more than 59 minutes with this approach. Passing "24 hr" or "60 min" or any combination of such will fail.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
0

I'd use a Dictionary for this, so there's no parsing at all involved. (It works well when there are fixed choices.) I'm more familiar with Delphi's UI controls than .NETs, so there might be a better way to populate the ComboBox than what I'm doing here, but I'm sure someone will let me know if there is and I can fix it.

(Code is Oxygene, but it should be easily translatable to C# or VB.Net.)

method MainForm.MainForm_Load(sender: System.Object; e: System.EventArgs);
var
  KC: Dictionary<String, Int32>.KeyCollection;
begin
  aItems := new Dictionary<String, Int32>;
  aItems.Add('15 min', 15);
  aItems.Add('30 min', 30);
  aItems.Add('1 hr', 60);
  aItems.Add('1 hr 30 min', 90);
  aItems.Add('2 hr', 120);
  aItems.Add('2 hr 30 min', 150);
  KC := aItems.Keys;
  for s in KC do
    comboBox2.Items.Add(s);
  comboBox2.DropDownStyle := ComboBoxStyle.DropDownList;
end;

method MainForm.comboBox2_SelectedIndexChanged(sender: System.Object; e: System.EventArgs);
begin
  // Safe since style is DropDownList. 
  label1.Text := aItems[comboBox2.SelectedItem.ToString].ToString(); 
end;
Ken White
  • 123,280
  • 14
  • 225
  • 444
-1

This should work:

   static int GetAllNumbersFromString(string timeString)
   {
    int min = 0;

    MatchCollection mc=Regex.Matches(timeString, @"\d+");

    if(timeString.Contains("hr") && mc.Count = 1)
    {

          min = mc[0] * 60;

    }
    else
    {

        if(mc.Count > 1)
        {
            min = mc[0] * 60 + mc[1];
        }
        else
        {
            min = mc[0];
        }
    }

    return min;
}
Bit
  • 1,068
  • 1
  • 11
  • 20