代码之家  ›  专栏  ›  技术社区  ›  Nap

如何删除日历的最后一周

  •  6
  • Nap  · 技术社区  · 14 年前

    我不知道为什么以前没有人问过这个问题。但是你有没有注意到asp:calendar在最后显示了一个额外的星期?

    例如,如果visibleMonth设置为2010-03-01,FirstDayOfWeek设置为Sunday: 它将显示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日

    我想知道为什么微软会在4月份展示最后一行。我试图在网上搜索一处房产,但它似乎不存在。

    我能想到的唯一解决方案是覆盖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;
        }
    }
    
    5 回复  |  直到 11 年前
        1
  •  7
  •   robert    13 年前

    很不错的。适用于大多数浏览器,但很适合Chrome11.0.696.71和SafariforWindows(尚未在Mac上测试)

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

    当您设置e.cell.visible=false时,它不会呈现元素。所以在chrome中,你最终得到了一个 <tr></tr> . chrome将其渲染为空行。由于我认为没有办法通过calendar控件设置tr元素的高度/样式,因此您最终会得到一个外观丑陋的日历,它在某些月份缺少第一行。

    如果将visible设置为false,则将height设置为0也不会执行任何操作。如果不将visible设置为false,只将height设置为0,则在chrome中仍然无法正确渲染。所以解决方法是将高度设置为

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

    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;
            }
        }
    
        2
  •  2
  •   TKTS    11 年前

    如果选择了weekText并选择了mode=“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>
    
        3
  •  1
  •   robert    13 年前

    好的,我有另一个解决办法。经过一些调整。希望能有所帮助。它有更多的功能,但如果你的日历点击率很高,它可能只节省1%的CPU:)。 确保连接 Calendar1_VisibleMonthChanged 事件到onvisibleMontChanged

    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;
        }
    
        4
  •  1
  •   Matt Sieker Will Castillo    13 年前
    <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="&amp;gt;&amp;gt;" PrevMonthText="&amp;lt;&amp;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;
       }
    
    }
    
        5
  •  1
  •   zacharydl    12 年前

    这是我使用的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