ASP.NET中编写月份和年份下拉列表的最佳方法是什么?

12

我有一个内部应用程序,需要为两个日期类型元素(月份年份)提供下拉列表。这些值不在数据库或其他信息库中。

我知道我可以通过将它们添加到类似于字典的对象中(我需要将月份与数字表示相关联,例如:一月=> 01),来设置所需值的列表:

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

由于我可以选择一个起始年份,并在通用列表中迭代到当前或当前+1年,因此年份的下拉列表将更容易。

是否有更好的方法处理这些数据元素?是否有内置的功能或者应该实现的好的设计模式?


有趣的问题,我曾经也有过同样的疑问。+1 - pyrocumulus
你需要本地化这个值吗? - Greg
本地化不是必需的,但如果已经存在本地化状态,那也无妨。 - Astra
9个回答

31
你可以使用这个方法获取所有月份的名称并循环遍历它们。
CultureInfo.CurrentCulture.DateTimeFormat.MonthNames

您可以这样使用它...将月份的索引作为下拉菜单的值

var months = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames;
for (int i = 0; i < months.Length; i++)
{
     ddl.Items.Add(new ListItem(months[i], i.ToString()));
}

太棒了!我喜欢StackOverflow——我每天至少能学到两个新东西。我已经在另一个答案中向@Jesse Brown的回答致敬,做出了自己的贡献。 - Cyberherbalist
我所能看到的唯一问题是:返回的月份名称数组的顺序是否会保持不变(如果顺序混乱,一月可能突然被分配为数字5)。那就是我对这种方法唯一的担忧。 - Astra
一定要查看DateTimeFormat的其他属性,例如AbbreviatedMonthNames。不要只是使用substring(0,3)!! - Simon_Weaver
要使用本地化的月份名称,请使用 Thread.CurrentThread.CurrentCulture.DateTimeFormat.MonthNames。 - Nikkelmann
months.DataSource = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames; months.DataBind();并且可以使用像 months.SelectedIndex + 1 这样的方式。 - Ali Humayun
显示剩余2条评论

5

扩展@Jesse Brown的答案...

使用 using System.Globalization 指令,我有以下代码:

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

这将产生一个下拉列表,看起来像这样:
01月 02月 03月 ... 12月
进一步的改进可能是通过添加以下内容使显示的月份为当前月份:
cboMonth.Text = DateTime.Now.Month.ToString("00") 
   + " " 
   + CultureInfo.CurrentCulture.DateTimeFormat.MonthNames.GetValue(DateTime.Now.Month);

循环结束后。

3
以下代码用于将月份下拉框加载为“选择”:
    private void LoadMonth()
    {
        ddlmonth.Items.Add(new ListItem("Select", 0.ToString()));
        var months = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames;
        for (int i = 0; i < months.Length-1; i++)
        {
            ddlmonth.Items.Add(new ListItem(months[i], (i+1).ToString()));
        }
    }

请提供一些关于您的代码的解释。这样您的答案将更有用。 - mastov

3

以下是我的解决方案,与@jesse-brown的解决方案(被接受的答案)非常相似

VB.NET:

在全局函数类中:

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

在ASPX页面上:
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

这个实现是用VB.NET编写的,因为这个Web应用程序正在使用它(遗留问题),但非常感谢您提供C#示例(我更喜欢的语言),我在此发布VB.NET以帮助VB.NET社区。


2
对于ASP.NET MVC,这是我正在做的事情。
注意:我更喜欢使用codebehind 来处理这种事情 - 它仍然是视图的一部分,视图构建一个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)
                });
            }
        }
    }

当我在我的模型类中使用public IEnumerable<SelectListItem> ExpirationMonthDropdown {时,我会收到以下错误提示:The name 'Model' does not exist in the current context - kez

1
 public void bind_month()
    {
        var months = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames;

        ddl_month.Items.Insert(0, new ListItem("--Select--", "0"));

        for (int i = 0; i < months.Length-1; i++)
        {
            ddl_month.Items.Add(new ListItem(months[i],(i+1).ToString()));
        }

    }

1

有人要求提供月份的数字表示方式。这是我的代码:

// DOB MONTHS
dob_month1.Items.Insert(0, new ListItem("Select", "")); 
var months = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames;
for (int i = 1; i < months.Length; i++)
{
    dob_month1.Items.Add(new ListItem(i.ToString(), i.ToString()));
}

这基本上与答案代码相同,只有一些小调整。

结果:

enter image description here


0

/尝试使用以下代码将所有月份绑定到下拉列表中,而无需使用数据库/

 public void GetMonthList(DropDownList ddl)
    {
        DateTime month = Convert.ToDateTime("1/1/2000");
        for (int i = 0; i < 12; i++)
        {
            DateTime NextMont = month.AddMonths(i);
            ListItem list = new ListItem();
            list.Text = NextMont.ToString("MMMM");
            list.Value = NextMont.Month.ToString();
            ddl.Items.Add(list);
        }
        //ddl.Items.Insert(0, "Select Month");
        ddl.Items.FindByValue(DateTime.Now.Month.ToString()).Selected = true;
    }

-1

1
您好,这里不鼓励仅提供链接或仅提供代码的答案。您能否编辑您的回答并解释如何解决提问者的问题? - Tim Malone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接