隐藏当月没有日期的行(自定义日历标签助手)

Hide rows without dates in current month (Custom Calendar Tag Helper)

关注本文: https://cpratt.co/bootstrap-4-responsive-calendar-asp-net-core-taghelper/ 我能够实现一个自定义日历标签助手,它只需要一个月和一年作为参数并显示该月的日历。

它显示标准日历,其中包含前几个月的一些天数和未来的几天。 我想要的是隐藏当月没有天数的任何行,所以基本上,有些月可能只有 5 行而不是标准日历中的 6 行。

我试图使用 css 隐藏某些单元格,但这仍然给我 6 行空白单元格。

查看文章中解释的示例代码笔:

https://codepen.io/chrisdpratt/pen/OOybam 如您所见,有一排日期不在那个月。 我只想显示当月有一些包含天数的行。

这是呈现 html.

的 c# 标签助手中的代码
[HtmlTargetElement("calendar", TagStructure = TagStructure.NormalOrSelfClosing)]
public class CalendarTagHelper : TagHelper  
{
    public int Month { get; set; }

    public int Year { get; set; }

    public List<CalendarEvent> Events { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "section";
        output.Attributes.Add("class", "calendar");
        output.Content.SetHtmlContent(GetHtml());
        output.TagMode = TagMode.StartTagAndEndTag;
    }

    private string GetHtml()
    {
        var monthStart = new DateTime(Year, Month, 1);
        var events = Events?.GroupBy(e => e.Date);

        var html = new XDocument(
            new XElement("div",
                new XAttribute("class", "container-fluid"),
                new XElement("header",
                    new XElement("h4",
                        new XAttribute("class", "display-4 mb-2 text-center"),
                        monthStart.ToString("MMMM yyyy")
                    ),
                    new XElement("div",
                        new XAttribute("class", "row d-none d-lg-flex p-1 bg-dark text-white"),
                        Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>().Select(d =>
                            new XElement("h5",
                                new XAttribute("class", "col-lg p-1 text-center"),
                                d.ToString()
                            )
                        )
                    )
                ),
                new XElement("div",
                    new XAttribute("class", "row border border-right-0 border-bottom-0"),
                    GetDatesHtml()
                )
            )
        );

        return html.ToString();

        IEnumerable<XElement> GetDatesHtml()
        {
            var startDate = monthStart.AddDays(-(int)monthStart.DayOfWeek);
            var dates = Enumerable.Range(0, 42).Select(i => startDate.AddDays(i));

            foreach (var d in dates)
            {
                if (d.DayOfWeek == DayOfWeek.Sunday && d != startDate)
                {
                    yield return new XElement("div",
                        new XAttribute("class", "w-100"),
                        String.Empty
                    );
                }

                var mutedClasses = "d-none d-lg-inline-block bg-light text-muted";
                yield return new XElement("div",
                    new XAttribute("class", $"day col-lg p-2 border border-left-0 border-top-0 text-truncate {(d.Month != monthStart.Month ? mutedClasses : null)}"),
                    new XElement("h5",
                        new XAttribute("class", "row align-items-center"),
                        new XElement("span",
                            new XAttribute("class", "date col-1"),
                            d.Day
                        ),
                        new XElement("small",
                            new XAttribute("class", "col d-lg-none text-center text-muted"),
                            d.DayOfWeek.ToString()
                        ),
                        new XElement("span",
                            new XAttribute("class", "col-1"),
                            String.Empty
                        )
                    ),
                    GetEventHtml(d)
                );
            }
        }

        IEnumerable<XElement> GetEventHtml(DateTime d)
        {
            return events?.SingleOrDefault(e => e.Key == d)?.Select(e =>
                new XElement("a",
                    new XAttribute("class", $"event d-block p-1 pl-2 pr-2 mb-1 rounded text-truncate small bg-{e.Type} text-white"),
                    new XAttribute("title", e.Title),
                    e.Title
                )
            ) ?? new[] {
                new XElement("p",
                    new XAttribute("class", "d-lg-none"),
                    "No events"
                )
            };
        }
    }
}

我知道我需要调整这条线 var dates = Enumerable.Range(0, 42).Select(i => startDate.AddDays(i)); 获得正确的范围,以便根本不会呈现当月没有天数的行,但我似乎无法理解它。

你只需要根据需要的周数来决定显示多少天,即42(天)就是6周。我只是选择了标准的 42,因为我希望日历始终保持相同的视觉高度。

无论如何,要计算要显示的周数,您可以使用类似的东西:

var weeks = (int)Math.Ceiling((DateTime.DaysInMonth(Year, Month) + (int)monthStart.DayOfWeek) / 7f);

然后,只需将 dates 初始化替换为:

var dates = Enumerable.Range(0, weeks * 7).Select(i => startDate.AddDays(i));