views:

635

answers:

4

I have an internal application that I needs to have a drop down list for two date type elements: Month and Year. These values are not in a database or other repository of information.

I know I could just setup a list with the values I need by adding them to a dictionary like object (I need to correlate the Month to the numerical representation, January => 01):

var months = new Dictionary<String,String>();
months.Add("01", "January");
...

The drop down list for the year will be a bit easier as I can just choose a starting year and iterate up to the current or current+1 year in a generic list.

Is there a better way to handle these data elements? Something built in, or a good design pattern that I should be implementing?

+9  A: 

You could use this to get a list of all the Month names and loop through it.

CultureInfo.CurrentCulture.DateTimeFormat.MonthNames

You can use it like this...using the index of the Month as the value for your dropdown

var months = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames;
for (int i = 0; i < months.Length; i++)
{
     ddl.Items.Add(new ListItem(months[i], i.ToString()));
}
Jab
Is there a way to corrolate a month name with the numeric representation (i.e. January => 1)?
Redbeard 0x0A
check the edit, I added it's usage.
Jab
The array returned by CultureInfo.InvariantCulture.DateTimeFormat.MonthNames contains contains "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", and "" in order. You can use a for loop to get the index for each value.
Greg
Great answer! I love StackOverflog -- I truly learn something new at least twice a day. I've added my contribution in homage to @Jesse Brown's answer in another answer.
Cyberherbalist
The only issue I see with this: Is the order of the returned array of Month Names going to remain the same (if the order gets messed up, it would be possible for January to all of a sudden be assigned the number 5). That is my only concern with this method.
Redbeard 0x0A
be sure to check out the other properties on DateTimeFormat - such as AbbreviatedMonthNames. Don't just do substring(0,3) !!
Simon_Weaver
+2  A: 

Extending @Jesse Brown's answer...

With a using System.Globalization directive, I have the following code:

for (int x = 0; x < 12; x++)
{
    cboMonth.Items.Add
    (
       (x+1).ToString("00") 
       + " " 
       + CultureInfo.CurrentCulture.DateTimeFormat.MonthNames.GetValue(x)
     );
}

This produces a dropdown list that looks like:

01 January 02 February 03 March ... 12 December

A further refinement might be to make the displayed month the current month by adding:

cboMonth.Text = DateTime.Now.Month.ToString("00") 
   + " " 
   + CultureInfo.CurrentCulture.DateTimeFormat.MonthNames.GetValue(DateTime.Now.Month);

After the for loop.

Cyberherbalist
+1  A: 

Here is my solution, which is very similar to @jesse-brown's solution (the accepted answer)

VB.NET:

In a global functions class:

Public Shared Function GetMonthList() As Generic.Dictionary(Of String, String)
    Dim months As New Generic.Dictionary(Of String, String)()
    For m As Int32 = 1 To 12
        months.Add(String.Format("{0:0#}", m), CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(m))
    Next

    Return months
End Function

On the ASPX page:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    ddMonth.DataSource = GlobalFunctions.GetMonthList()
    ddMonth.DataValueField = "Key"
    ddMonth.DataTextField = "Value"
    ddMonth.DataBind()

End Sub

This implementation is in VB.NET because that happens to be what this webapp is using (legacy), however thank you very much for the examples in C# (my preferred language), I'm posting the VB.NET here to help the VB.NET community as well.

Redbeard 0x0A
+1  A: 

For ASP.NET MVC this is what I'm doing.

Note I prefer to use a codebehind for things like this - its still part of the view and there's nothing wrong with the view constructing a SelectList.

PaymentControl.ascx

 <%= Html.DropDownList("ExpirationMonth", ExpirationMonthDropdown)%> / 
 <%= Html.DropDownList("ExpirationYear", ExpirationYearDropdown)%>

PaymentControl.ascx.cs

public partial class PaymentControl : ViewUserControl<CheckoutModel>
    {
        public IEnumerable<SelectListItem> ExpirationMonthDropdown
        {
            get
            {
                return Enumerable.Range(1, 12).Select(x =>

                    new SelectListItem()
                    {
                        Text = CultureInfo.CurrentCulture.DateTimeFormat.AbbreviatedMonthNames[x - 1] + " (" + x + ")",
                        Value = x.ToString(),
                        Selected = (x == Model.ExpirationMonth)
                    });
            }
        }

        public IEnumerable<SelectListItem> ExpirationYearDropdown
        {
            get
            {
                return Enumerable.Range(DateTime.Today.Year, 20).Select(x =>

                new SelectListItem()
                {
                    Text = x.ToString(),
                    Value = x.ToString(),
                    Selected = (x == Model.ExpirationYear)
                });
            }
        }
    }
Simon_Weaver