如何删除日历的最后一周

发布于 2024-08-26 10:45:46 字数 1072 浏览 6 评论 0原文

我不确定为什么其他人以前没有问过这个问题。但是您是否注意到 asp:Calendar 在末尾显示了额外的一周?

例如,如果 VisibleMonth 设置为 2010-03-01,FirstDayOfWeek 设置为星期日: 它将显示 6 周。

  1. 2月28日至3月6日
  2. 3月7日至3月13日
  3. 3月14日至3月20日
  4. 3月21日至3月27日
  5. 3月28日至4月3日
  6. 4月4日至4月10日

我想知道为什么微软显示最后一行完全是在四月。我试图在网上搜索房产,但它似乎不存在。

我能想到的唯一解决方案是覆盖 Pre_Render 并检查所有单个日期是否仍在 VisibleDate 的一周内。但当然这是一个极端的检查,因为控件的每次渲染都会显示它。

这是我的工作。

protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
    int dayOfWeek = Convert.ToInt16(e.Day.Date.DayOfWeek);
    int compensate = dayOfWeek - Convert.ToInt16(DayOfWeek.Sunday);
    DateTime WeekStart = e.Day.Date.AddDays(-1 * compensate);
    DateTime WeekEnd = WeekStart.AddDays(6);

    // If the start and end of the week does not have relevance to the current month
    if (WeekStart.Month != Calendar1.VisibleDate.Month &&
        WeekEnd .Month != Calendar1.VisibleDate.Month)
    {
        e.Cell.Text = "";
        e.Cell.Height = 0;
        e.Cell.Visible = false;
    }
}

I am not sure why other people have not asked this before. But have you notice that the asp:Calendar shows an extra week at the end?

For example if the VisibleMonth is set to 2010-03-01 and FirstDayOfWeek to Sunday:
It will show 6 weeks.

  1. Feb 28 to March 6
  2. March 7 to March 13
  3. March 14 to March 20
  4. March 21 to March 27
  5. March 28 to April 3
  6. April 4 to April 10

I was wondering why Microsoft shows the last Row which is entirely on April. I tried to search the net for a property but it does not seem to be existing.

The only solution that I could think of is to override the Pre_Render and check all individual date if they are still within the week of the VisibleDate. But of course that is an extreme checking since each rendering of the control shows it.

Here is my work around.

protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
    int dayOfWeek = Convert.ToInt16(e.Day.Date.DayOfWeek);
    int compensate = dayOfWeek - Convert.ToInt16(DayOfWeek.Sunday);
    DateTime WeekStart = e.Day.Date.AddDays(-1 * compensate);
    DateTime WeekEnd = WeekStart.AddDays(6);

    // If the start and end of the week does not have relevance to the current month
    if (WeekStart.Month != Calendar1.VisibleDate.Month &&
        WeekEnd .Month != Calendar1.VisibleDate.Month)
    {
        e.Cell.Text = "";
        e.Cell.Height = 0;
        e.Cell.Visible = false;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

‖放下 2024-09-02 10:45:47

好吧,我有另一个解决方案。经过一番调整。希望它有帮助。它的功能稍微多一些,但如果你的日历点击量很大,它可能只节省 1% 的 cpu :)。 确保将 Calendar1_VisibleMonthChanged 事件附加到 OnVisibleMonthChanged

private DateTime fromDate;
private DateTime toDate;
private Boolean blnBrowserDoesntSupportsEmptyRow = Request.Browser.Browser=="Chrome" ||
                                                       Request.Browser.Browser=="Safari";

    protected void Page_Load(object sender, EventArgs e){
        if (!Page.IsPostBack){
            setFromToDates(new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1));
        }
    }

    protected void Calendar1_VisibleMonthChanged(object sender, MonthChangedEventArgs e){
        setFromToDates(e.NewDate);
    }

    protected void setFromToDates(DateTime monthStart){

        DayOfWeek dw = (DayOfWeek)Calendar1.FirstDayOfWeek;
        if (dw == (DayOfWeek)7) dw = (DayOfWeek)0;


        if (monthStart.DayOfWeek == dw){
            this.fromDate = monthStart;// if 1st day of calendar is also 1st of the month. just set as is
        }else{
            int dayOfWeek = Convert.ToInt16(monthStart.DayOfWeek);
            dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
            int compensate = dayOfWeek - Convert.ToInt16(dw);
            this.fromDate = monthStart.AddDays(-1 * compensate);// set FromDate to the beggning day of the calendar. I.e may start from e.g. 25th of the previous month
        }

        this.toDate = monthStart.AddMonths(1);
        if (this.toDate.DayOfWeek != dw)
        {
            int dayOfWeek = Convert.ToInt16(this.toDate.DayOfWeek);
            dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
            int compensate = dayOfWeek - Convert.ToInt16(dw);
            this.toDate=this.toDate.AddDays(7-compensate);
        }
    }








    protected void Calendar1_DayRender(object sender, DayRenderEventArgs e){
        // hide extra week
        hideExtraWeek(sender, e);
    }

    // returns weather or not the given day is hidden
    protected Boolean hideExtraWeek(object sender, DayRenderEventArgs e){
            Boolean isVisibleDay = e.Day.Date >= this.fromDate && e.Day.Date < this.toDate;

            // If the start and end of the week does not have relevance to the current month
            if (!isVisibleDay){
                e.Cell.Text = "";
                e.Cell.Height = 1; // fix for chrome. Visible=false leaves a blank row even when there are no <td>s in the <tr>
                e.Cell.Visible = blnBrowserDoesntSupportsEmptyRow;
             }
        return !isVisibleDay;
    }

Ok i have another solution. After some tweaking. Hopefully it helps. It has slightly more functions but if your calendar gets alotof hits, it might just save a 1% of cpu :). Make sure to attach the Calendar1_VisibleMonthChanged event to OnVisibleMonthChanged

private DateTime fromDate;
private DateTime toDate;
private Boolean blnBrowserDoesntSupportsEmptyRow = Request.Browser.Browser=="Chrome" ||
                                                       Request.Browser.Browser=="Safari";

    protected void Page_Load(object sender, EventArgs e){
        if (!Page.IsPostBack){
            setFromToDates(new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1));
        }
    }

    protected void Calendar1_VisibleMonthChanged(object sender, MonthChangedEventArgs e){
        setFromToDates(e.NewDate);
    }

    protected void setFromToDates(DateTime monthStart){

        DayOfWeek dw = (DayOfWeek)Calendar1.FirstDayOfWeek;
        if (dw == (DayOfWeek)7) dw = (DayOfWeek)0;


        if (monthStart.DayOfWeek == dw){
            this.fromDate = monthStart;// if 1st day of calendar is also 1st of the month. just set as is
        }else{
            int dayOfWeek = Convert.ToInt16(monthStart.DayOfWeek);
            dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
            int compensate = dayOfWeek - Convert.ToInt16(dw);
            this.fromDate = monthStart.AddDays(-1 * compensate);// set FromDate to the beggning day of the calendar. I.e may start from e.g. 25th of the previous month
        }

        this.toDate = monthStart.AddMonths(1);
        if (this.toDate.DayOfWeek != dw)
        {
            int dayOfWeek = Convert.ToInt16(this.toDate.DayOfWeek);
            dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
            int compensate = dayOfWeek - Convert.ToInt16(dw);
            this.toDate=this.toDate.AddDays(7-compensate);
        }
    }








    protected void Calendar1_DayRender(object sender, DayRenderEventArgs e){
        // hide extra week
        hideExtraWeek(sender, e);
    }

    // returns weather or not the given day is hidden
    protected Boolean hideExtraWeek(object sender, DayRenderEventArgs e){
            Boolean isVisibleDay = e.Day.Date >= this.fromDate && e.Day.Date < this.toDate;

            // If the start and end of the week does not have relevance to the current month
            if (!isVisibleDay){
                e.Cell.Text = "";
                e.Cell.Height = 1; // fix for chrome. Visible=false leaves a blank row even when there are no <td>s in the <tr>
                e.Cell.Visible = blnBrowserDoesntSupportsEmptyRow;
             }
        return !isVisibleDay;
    }
墟烟 2024-09-02 10:45:47
<asp:Calendar ID="Calendar1" runat="server" CellPadding="1" CellSpacing="0"
 Width="600px" FirstDayOfWeek="Monday" BorderColor="#a1a1a1"
BorderWidth="1" BorderStyle="None" ShowGridLines="True" ShowDescriptionAsToolTip="True"
NextPrevStyle-CssClass=""
Height="500px" OnDayRender="Calendar1_DayRender" 
SelectionMode="None"  NextMonthText="&gt;&gt;" PrevMonthText="&lt;&lt;">
<OtherMonthDayStyle BorderStyle="None" />
</asp:Calendar>

bool weekstart = false;
int[] longmonths = new int[] { 1, 3, 5, 7, 8, 10, 12 };// 31 days in a Month
int[] shortmonths = new int[] { 4, 6, 9, 11 };// 30 days in a Month

protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{

   if (e.Day.IsOtherMonth)
   {
        e.Cell.Text = String.Empty;
        e.Cell.Height = 0;
        if (e.Day.Date.DayOfWeek == DayOfWeek.Monday )//Monday is FirstDayOfWeek
        {
          if (shortmonths.Contains(e.Day.Date.Month) && e.Day.Date.Day == 24)
          {
             weekstart = true;
          }
          else if (longmonths.Contains(e.Day.Date.Month) && e.Day.Date.Day == 25)
          {
             weekstart = true;
          }
        }
        if (weekstart)
        {
           e.Cell.Visible = false;
        }
   }
   else if (!e.Day.IsOtherMonth)
   {
      weekstart = false;
   }

}
<asp:Calendar ID="Calendar1" runat="server" CellPadding="1" CellSpacing="0"
 Width="600px" FirstDayOfWeek="Monday" BorderColor="#a1a1a1"
BorderWidth="1" BorderStyle="None" ShowGridLines="True" ShowDescriptionAsToolTip="True"
NextPrevStyle-CssClass=""
Height="500px" OnDayRender="Calendar1_DayRender" 
SelectionMode="None"  NextMonthText="&gt;&gt;" PrevMonthText="&lt;&lt;">
<OtherMonthDayStyle BorderStyle="None" />
</asp:Calendar>

bool weekstart = false;
int[] longmonths = new int[] { 1, 3, 5, 7, 8, 10, 12 };// 31 days in a Month
int[] shortmonths = new int[] { 4, 6, 9, 11 };// 30 days in a Month

protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{

   if (e.Day.IsOtherMonth)
   {
        e.Cell.Text = String.Empty;
        e.Cell.Height = 0;
        if (e.Day.Date.DayOfWeek == DayOfWeek.Monday )//Monday is FirstDayOfWeek
        {
          if (shortmonths.Contains(e.Day.Date.Month) && e.Day.Date.Day == 24)
          {
             weekstart = true;
          }
          else if (longmonths.Contains(e.Day.Date.Month) && e.Day.Date.Day == 25)
          {
             weekstart = true;
          }
        }
        if (weekstart)
        {
           e.Cell.Visible = false;
        }
   }
   else if (!e.Day.IsOtherMonth)
   {
      weekstart = false;
   }

}
◇流星雨 2024-09-02 10:45:47

这是我使用的VB代码。必要时它将删除顶部和底部的空行。它使用私有变量。此方法在Chrome或Safari中似乎没有任何问题。

Private _hideEmptyWeek As Boolean

Protected Sub Calendar1_DayRender(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DayRenderEventArgs) Handles Calendar1.DayRender

    If e.Day.IsOtherMonth Then

        '' Hide first week if empty
        If e.Day.Date = e.Day.Date.AddDays(-e.Day.Date.Day + 1).AddMonths(1).AddDays(-7) Then ' If this date is a full week before next month
            _hideEmptyWeek = True
        End If


        '' Hide last week if empty
        If e.Day.Date.DayOfWeek = DayOfWeek.Sunday And e.Day.Date.Day < 7 Then ' If this is the first Sunday of next month
            _hideEmptyWeek = True
        End If


        '' Hide cell if we are in an empty week
        If _hideEmptyWeek = True Then
            e.Cell.Visible = False
        End If
    Else
        _hideEmptyWeek = False
    End If
End Sub

Here is the VB code I use. It will remove empty rows at both the top and bottom when necessary. It uses a private variable. This method does not seem to have any issues in Chrome or Safari.

Private _hideEmptyWeek As Boolean

Protected Sub Calendar1_DayRender(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DayRenderEventArgs) Handles Calendar1.DayRender

    If e.Day.IsOtherMonth Then

        '' Hide first week if empty
        If e.Day.Date = e.Day.Date.AddDays(-e.Day.Date.Day + 1).AddMonths(1).AddDays(-7) Then ' If this date is a full week before next month
            _hideEmptyWeek = True
        End If


        '' Hide last week if empty
        If e.Day.Date.DayOfWeek = DayOfWeek.Sunday And e.Day.Date.Day < 7 Then ' If this is the first Sunday of next month
            _hideEmptyWeek = True
        End If


        '' Hide cell if we are in an empty week
        If _hideEmptyWeek = True Then
            e.Cell.Visible = False
        End If
    Else
        _hideEmptyWeek = False
    End If
End Sub
耳根太软 2024-09-02 10:45:46

很不错。适用于大多数浏览器,但适用于 Windows 的 Chrome 11.0.696.71 和 Safari(尚未在 Mac 上进行测试)

某些月份,日历控件会在月初显示额外的一周。 (当该月的第一天是一周的第一天时。)

当您设置 e.cell.Visible=false 时,它​​不会渲染 elements 。所以在 chrome 中你最终会得到一行 。 Chrome 将其呈现为空白行。而且由于我认为没有办法通过日历控件设置 TR 元素高度/样式,因此您最终会得到一个看起来丑陋的日历,在某些月份中缺少第一行。

当您设置 Visible=false 时,将高度设置为 0 也不会执行任何操作。如果您不设置 Visible=false 并仅将 height =0 设置,它仍然无法在 chrome 中正确渲染。所以解决方案是将高度设置为 1

这是我修改后的解决方案。

onrowrender

protected void Calendar1_DayRender(object sender, DayRenderEventArgs e){
    hideExtraWeek(sender, e, (DayOfWeek)Calendar1.FirstDayOfWeek);
}

函数

    protected void hideExtraWeek(object sender, DayRenderEventArgs e, DayOfWeek dw){
        if (dw == (DayOfWeek)7) dw = (DayOfWeek)0; // FirstDayOfweek returns 7 when set to default, But it's zero based so valid values are 0 to 6
        Boolean blnBrowserDoesntSupportsEmptyRow= Request.Browser.Browser=="Chrome" ||
                                            Request.Browser.Browser=="Safari";

        int dayOfWeek = Convert.ToInt16(e.Day.Date.DayOfWeek);
        int compensate = dayOfWeek - Convert.ToInt16(dw);
        DateTime WeekStart = e.Day.Date.AddDays(-1 * compensate);
        DateTime WeekEnd = WeekStart.AddDays(6);

        // If the start and end of the week does not have relevance to the current month
        if (WeekStart.Month==WeekEnd.Month && e.Day.IsOtherMonth){
            e.Cell.Text = "";
            e.Cell.Height = 1; // fix for chrome. Visible=false leaves a blank row even when there are no <td>s in the <tr>
            e.Cell.Visible = blnBrowserDoesntSupportsEmptyRow;
        }
    }

very nice. Works with most browsers but is fugly with Chrome 11.0.696.71 And Safari for windows (havn't tested on mac)

For some months the calendar control displays the extra week at the start of the month. (when the 1st of the month is the first day of the week.)

When you set e.cell.Visible=false it doesn't render elements . So in chrome you end up with a row <tr></tr> . Chrome renders this as a blank row. And since i don't think there's a way to set the TR element height/style via the calendar control, you end up with an ugly looking calendar that's missing it's first row for certain months.

Also setitng height to 0 does nothing when you set Visible=false. If you don't set Visible=false and just put height =0 it still doesn't render correctly in chrome. So the solution is to set height to 1

Here's my modified solution.

the onrowrender

protected void Calendar1_DayRender(object sender, DayRenderEventArgs e){
    hideExtraWeek(sender, e, (DayOfWeek)Calendar1.FirstDayOfWeek);
}

the function

    protected void hideExtraWeek(object sender, DayRenderEventArgs e, DayOfWeek dw){
        if (dw == (DayOfWeek)7) dw = (DayOfWeek)0; // FirstDayOfweek returns 7 when set to default, But it's zero based so valid values are 0 to 6
        Boolean blnBrowserDoesntSupportsEmptyRow= Request.Browser.Browser=="Chrome" ||
                                            Request.Browser.Browser=="Safari";

        int dayOfWeek = Convert.ToInt16(e.Day.Date.DayOfWeek);
        int compensate = dayOfWeek - Convert.ToInt16(dw);
        DateTime WeekStart = e.Day.Date.AddDays(-1 * compensate);
        DateTime WeekEnd = WeekStart.AddDays(6);

        // If the start and end of the week does not have relevance to the current month
        if (WeekStart.Month==WeekEnd.Month && e.Day.IsOtherMonth){
            e.Cell.Text = "";
            e.Cell.Height = 1; // fix for chrome. Visible=false leaves a blank row even when there are no <td>s in the <tr>
            e.Cell.Visible = blnBrowserDoesntSupportsEmptyRow;
        }
    }
绝對不後悔。 2024-09-02 10:45:46

如果您有 SelectWeekText 和 SelectionMode="DayWeek" 或 "DayWeekMonth",则会遇到隐藏周的周选择标记仍然显示的问题。以下是我使用一点 JQuery 实现的方法。

 Sub cal_DayRender(ByVal sender As Object, ByVal e As DayRenderEventArgs)
      If HideExtraWeek(e, If(Cal.FirstDayOfWeek = WebControls.FirstDayOfWeek.Default, Threading.Thread.CurrentThread.CurrentUICulture.DateTimeFormat.FirstDayOfWeek, Cal.FirstDayOfWeek)) Then
          e.Cell.Style("display") = "none"
          e.Cell.CssClass = "hiddenWeek"
          Exit Sub
      End If
      'do other render stuff here
 End Sub

Private Function HideExtraWeek(ByVal e As DayRenderEventArgs, ByVal startOfWeekDay As Integer) As Boolean
    If e.Day.IsOtherMonth Then
        'hide empty weeks, logic credited to Robert
        Dim currDay As Integer = e.Day.Date.DayOfWeek
        Dim weekStart As DateTime = e.Day.Date.AddDays(startOfWeekDay - currDay) 'first day of the week
        Dim weekEnd As DateTime = weekStart.AddDays(6)

        Return (weekStart.Month = weekEnd.Month) 'the entire week is part of the other month
    End If
    Return False
End Function

<script type="text/javascript">
        $(document).ready(function() {
             $("td.hiddenWeek").parent().hide();
        }
</script>

If you have SelectWeekText and SelectionMode="DayWeek" or "DayWeekMonth", you'll have issues with the week selection markup still showing up for the hidden week. Here's how I did it with a little bit of JQuery.

 Sub cal_DayRender(ByVal sender As Object, ByVal e As DayRenderEventArgs)
      If HideExtraWeek(e, If(Cal.FirstDayOfWeek = WebControls.FirstDayOfWeek.Default, Threading.Thread.CurrentThread.CurrentUICulture.DateTimeFormat.FirstDayOfWeek, Cal.FirstDayOfWeek)) Then
          e.Cell.Style("display") = "none"
          e.Cell.CssClass = "hiddenWeek"
          Exit Sub
      End If
      'do other render stuff here
 End Sub

Private Function HideExtraWeek(ByVal e As DayRenderEventArgs, ByVal startOfWeekDay As Integer) As Boolean
    If e.Day.IsOtherMonth Then
        'hide empty weeks, logic credited to Robert
        Dim currDay As Integer = e.Day.Date.DayOfWeek
        Dim weekStart As DateTime = e.Day.Date.AddDays(startOfWeekDay - currDay) 'first day of the week
        Dim weekEnd As DateTime = weekStart.AddDays(6)

        Return (weekStart.Month = weekEnd.Month) 'the entire week is part of the other month
    End If
    Return False
End Function

<script type="text/javascript">
        $(document).ready(function() {
             $("td.hiddenWeek").parent().hide();
        }
</script>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文