如何在ViewModel上创建可变长度下拉列表而不重复c#中的代码?

如何在ViewModel上创建可变长度下拉列表而不重复c#中的代码?,c#,arrays,list,viewmodel,dropdownlistfor,C#,Arrays,List,Viewmodel,Dropdownlistfor,我是一个新手开发人员,我需要填充一个带有日期的下拉列表,以便网站访问者可以选择这些日期来检索某些数据 这个列表是不寻常的,因为它必须从上个月一直向后填充到一年前。因此,上个月将是列表中的第一个条目,上个月将紧随其后。例如,如果今天是2017年7月5日,下拉列表将如下所示: Jun 2017 May 2017 Apr 2017 Mar 2017 Feb 2017 Jan 2017 Dec 2016 and so on . . . 每个月列表都会变长,所以我无法为列表编码固定长度。我提出了以下代码

我是一个新手开发人员,我需要填充一个带有日期的下拉列表,以便网站访问者可以选择这些日期来检索某些数据

这个列表是不寻常的,因为它必须从上个月一直向后填充到一年前。因此,上个月将是列表中的第一个条目,上个月将紧随其后。例如,如果今天是2017年7月5日,下拉列表将如下所示:

Jun 2017
May 2017
Apr 2017
Mar 2017
Feb 2017
Jan 2017
Dec 2016
and so on . . .
每个月列表都会变长,所以我无法为列表编码固定长度。我提出了以下代码,但无法生成:

[RequireLogin]
public ActionResult Index()
{
    bool firstItem = true;
    int x = -1;
    int y = 1;
    int daysFromStartDate = beginDate.Date.Subtract(currentDate).Days;
    List<SelectListItem> items = new List<SelectListItem>();

    while (daysFromStartDate >= 30)
    {
        DateTime previousMonth = DateTime.Now.Date.AddMonths(x);
        string pMonth = previousMonth.ToString("MMM");
        string pYear = previousMonth.ToString("YYYY");
        Int32.TryParse(pMonth, out thisMonth);
        Int32.TryParse(pYear, out thisYear);
        if (firstItem)
            firstItem = false;
            SelectListItem item[y] = new SelectListItem() { Text = pMonth + " " + pYear, Value = pMonth, Selected = true };  //<- #1
        else
            SelectListItem item[y]= new SelectListItem() { Text = pMonth + " " + pYear, Value = pMonth, Selected = false };  //<- #2
        items.Add(item[y]);                                                                                                  //<- #3
        x = x--;
        y = y++;
    }
    ViewBag.MonthList = items;
    return View();
}
这是一个棘手的(无论如何对我来说)。然而,弗拉德·斯特里亚普科(Vlad Stryapko)让我走上了正确的道路,我用了几句话,让他的解决方案(我接受了)奏效了。还有另一个问题,但与我原来的帖子无关,所以我将为此单独发布一个问题。这是我的最终代码:

我的ViewModel

        public SelectList MonthList { get; set; }


        public SelectList ReverseMonthsLists()
        {
            var stringViewOfDates = GetDates().Select(_ => _.ToString("MMM yyyy")).ToList();

            var list = new List<SelectListItem>();
            list.Add(new SelectListItem { Selected = true, Text = stringViewOfDates[0], Value = stringViewOfDates[0] });

            for (int i = 1; i < stringViewOfDates.Count(); i++)
            {
                list.Add(new SelectListItem { Selected = false, Text = stringViewOfDates[i], Value = stringViewOfDates[i] });
            }
            var selectList = new SelectList(list);
            return selectList;
        }


        public static IEnumerable<DateTime> GetDates()
        {
            DateTime startDate = new DateTime(2017, 6, 1).Date;
            var currentDate = DateTime.Now.Date;

            int numberOfMonthsToShow = (currentDate.Year - startDate.Year) * 12 + currentDate.Month - startDate.Month;
            if (numberOfMonthsToShow == 0)
                numberOfMonthsToShow = 1;

            var dates = new List<DateTime>(numberOfMonthsToShow);
            for (int i = 0; i < numberOfMonthsToShow; i++)
            {
                dates.Add(currentDate);
                currentDate = currentDate.AddMonths(-1);
            }
            return dates;
        }

代码现在可以编译了,但我得到的是下拉列表中的“System.Web.Mvc.SelectListItem”。我将在另一个帖子中提出这一问题,因为我认为我不允许在这里再问第二个问题。

我还不太明白您需要什么,因此,这里有一个示例,说明如何创建一个从当前日期开始并包含12个月的日期列表

public static IEnumerable<DateTime> GetDates()
{
    var currentDate = DateTime.Now;
    var numberOfMonthsToShow = 12;
    var dates = new List<DateTime>(numberOfMonthsToShow);
    for (int i = 0; i < numberOfMonthsToShow; i++)
    {
        dates.Add(currentDate);
        currentDate = currentDate.AddMonths(-1);
    }
    return dates;
}
现在您已经有了字符串,可以将它们添加到SelectList。我现在没有ASP.NETMVC,但它应该很简单。比如:

var list = new List<SelectListItem>();
list.Add(new SelectListItem { Selected = true, Text = stringViewOfDates[0], Value = stringViewOfDates[0]})

for (int i = 1; i < stringView.Count(); i++)
{
  list.Add(new SelectListItem { Selected = false, Text = stringViewOfDates[i], Value = stringViewOfDates[i]);
}

var selectList = new SelectList(list);
var list=newlist();
添加(新SelectListItem{Selected=true,Text=stringViewOfDates[0],Value=stringViewOfDates[0]})
对于(int i=1;i

对于“给我上个月”的任务,您有很多代码似乎是多余的。请尝试我提供的代码,或者解释为什么您需要如此复杂的代码。我可能缺少您的一些逻辑。

我还不完全了解您需要的内容。因此,下面是一个示例,说明如何从当前日期开始构建日期列表,并包含12个月

public static IEnumerable<DateTime> GetDates()
{
    var currentDate = DateTime.Now;
    var numberOfMonthsToShow = 12;
    var dates = new List<DateTime>(numberOfMonthsToShow);
    for (int i = 0; i < numberOfMonthsToShow; i++)
    {
        dates.Add(currentDate);
        currentDate = currentDate.AddMonths(-1);
    }
    return dates;
}
现在您有了字符串,可以将它们添加到SelectList。我现在没有ASP.NET MVC,但它应该非常简单。类似于:

var list = new List<SelectListItem>();
list.Add(new SelectListItem { Selected = true, Text = stringViewOfDates[0], Value = stringViewOfDates[0]})

for (int i = 1; i < stringView.Count(); i++)
{
  list.Add(new SelectListItem { Selected = false, Text = stringViewOfDates[i], Value = stringViewOfDates[i]);
}

var selectList = new SelectList(list);
var list=newlist();
添加(新SelectListItem{Selected=true,Text=stringViewOfDates[0],Value=stringViewOfDates[0]})
对于(int i=1;i

“给我上个月的时间”的任务中,您有很多代码似乎是多余的。请尝试我提供的代码,或者解释为什么您需要如此复杂的代码。我可能缺少您的一些逻辑。

给定了一个获取日期列表的通用函数:-

public static IEnumerable<string> ReverseMonthList(string format, DateTime start, int count)
    {
        return Enumerable.Range(0, count).Select(n => start.AddMonths(-(n + 1)).ToString(format));
    }
给予


给定了一个获取日期列表的通用函数:-

public static IEnumerable<string> ReverseMonthList(string format, DateTime start, int count)
    {
        return Enumerable.Range(0, count).Select(n => start.AddMonths(-(n + 1)).ToString(format));
    }
给予

这个列表是不寻常的,因为它必须从上个月一直向后填充到一年前

这很容易。首先-生成日期。您有开始日期(上个月)和所需的总月数(12)。然后将每个日期投影到
SelectListItem

var today = DateTime.Today;
var startOfMonth = new DateTime(today.Year, today.Month, 1);

var items = from i in Enumerable.Range(1, 12)
            let date = startOfMonth.AddMonths(-i)
            select new SelectListItem { 
                Text = date.ToString("MMM yyyy"), 
                Value = date.ToString("MMM"), 
                Selected = i == 1
            };

ViewBag.MonthList = items.ToList();
注:

  • 您应该计算相对于当前月初的日期。否则,您可能会遇到2月29日的问题
  • 使用字符串格式以所需格式生成日期。不要格式化日期的某些部分并将其连接起来
  • 年份格式字符串为小写
    yyyy
  • SelectListItem项[y]=…
    语法不正确。它是赋值和声明的混合体。如果要在列表中赋值项,则应按索引引用该项
    item[y]=…
    。但是您应该先检查列表是否包含足够的项目。实际上,您真正需要做的是在列表中添加一个项目,这是通过
    项目来实现的。添加(…)
  • 考虑学习-它允许您编写查询(以声明方式)以方便地筛选、项目等数据
  • 这个列表是不寻常的,因为它必须从上个月一直向后填充到一年前

    这很容易。首先-生成日期。您有开始日期(上个月)和所需的总月数(12)。然后将每个日期投影到
    SelectListItem

    var today = DateTime.Today;
    var startOfMonth = new DateTime(today.Year, today.Month, 1);
    
    var items = from i in Enumerable.Range(1, 12)
                let date = startOfMonth.AddMonths(-i)
                select new SelectListItem { 
                    Text = date.ToString("MMM yyyy"), 
                    Value = date.ToString("MMM"), 
                    Selected = i == 1
                };
    
    ViewBag.MonthList = items.ToList();
    
    注:

  • 您应该计算相对于当前月初的日期。否则,您可能会遇到2月29日的问题
  • 使用字符串格式以所需格式生成日期。不要格式化日期的某些部分并将其连接起来
  • 年份格式字符串为小写
    yyyy
  • SelectListItem项[y]=…
    语法不正确。它是赋值和声明的混合体。如果要在列表中赋值项,则应按索引引用该项
    item[y]=…
    。但是您应该先检查列表是否包含足够的项目。实际上,您真正需要做的是在列表中添加一个项目,这是通过
    项目来实现的。添加(…)
  • 考虑学习-它允许您编写查询(以声明方式)以方便地筛选、项目等数据
  • 这是一个控制台应用程序

       var startDate = DateTime.Now.Date;
    
        var days = new List<Tuple<string, string>>();
    
        int totalMonths = 12;
    
        for (int i = 1; i < totalMonths; i++)
        {
            var tempDay = startDate.AddMonths(-i);
            days.Add(new Tuple<string, string>($"{tempDay.ToString("MMM")} {tempDay.ToString("yyyy")}", tempDay.ToString("MMM")));
        }
    
        foreach (var d in days)
        {
            Console.WriteLine(d.Item1);
        }
    
    var startDate=DateTime.Now.Date;
    var days=新列表();
    整数总月份=12;
    对于(int i=1;i
    输出 2017年6月 2017年5月 2017年4月 2017年3月 2017年2月 2017年1月 2016年12月 2016年11月 2016年10月 2016年9月 2016年8月

    出于测试目的,我使用了tuple.Us
    var ans = Enumerable.Range(1, 12).Select(p => start.AddMonths(-p).ToString("MMM yy")).ToList();