2010-03-25 19 views
6

Nie jestem pewien, dlaczego inne osoby wcześniej o to nie pytały. Ale czy zauważyłeś, że asp: Kalendarz pokazuje dodatkowy tydzień na końcu?Jak usunąć ostatni tydzień z kalendarza

Na przykład, jeśli VisibleMonth jest ustawiony na 2010-03-01 i FirstDayOfWeek na niedzielę: Wyświetli 6 tygodni.

  1. 28 lutego 6 marca
  2. 07 marca do 13 marca
  3. 14 marca 20 marca
  4. 21 marca do 27 marca
  5. 28 marca 3 kwietnia
  6. 4 kwietnia kwietnia 10

Zastanawiam się, dlaczego Microsoft pokazuje ostatni wiersz, który jest w całości w kwietniu. Próbowałem przeszukać sieć pod kątem właściwości, ale wygląda na to, że nie istnieje.

Jedynym rozwiązaniem, które mogłem wymyślić jest zastąpienie Pre_Render i sprawdzić wszystkie indywidualne daty, jeśli są nadal w ciągu tygodnia VisibleDate. Ale oczywiście jest to ekstremalne sprawdzanie, ponieważ pokazuje je każde renderowanie kontrolki.

Oto moja praca.

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; 
    } 
} 

Odpowiedz

7

bardzo ładne. Współpracuje z większością przeglądarek, ale jest niezawodny z Chrome 11.0.696.71 i Safari dla Windows (nie testowany na Macu)

Przez kilka miesięcy kontrolka kalendarza wyświetla dodatkowy tydzień na początku miesiąca. (gdy pierwszy dzień miesiąca jest pierwszym dniem tygodnia.)

Po ustawieniu e.cell.Visible = false nie renderuje elementów. Tak więc w chrome kończy się wiersz <tr></tr>. Chrome renderuje to jako pusty wiersz. A ponieważ nie sądzę, że istnieje sposób na ustawienie wysokości/stylu elementu TR za pomocą kontrolki kalendarza, kończy się to brzydko wyglądającym kalendarzem, w którym brakuje pierwszego wiersza przez kilka miesięcy.

Ustawienie wysokości na 0 nic nie robi po ustawieniu Visible = false. Jeśli nie ustawisz Visible = false i po prostu ustaw wysokość = 0, to nadal nie wyświetla się poprawnie w chrome. Rozwiązaniem jest ustawienie wysokości na

Oto moje zmodyfikowane rozwiązanie.

onrowrender

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

funkcja

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; 
     } 
    } 
1

Ok i ma innego rozwiązania. Po kilku poprawkach. Mam nadzieję, że to pomaga. Ma nieco więcej funkcji, ale jeśli twój kalendarz dostanie dużo trafień, może po prostu zaoszczędzić 1% cpu :). Upewnij się, aby dołączyć do zdarzenia 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; 
    } 
1
<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; 
    } 

} 
1

Oto kod VB używam. W razie potrzeby usunie puste wiersze, zarówno na górze, jak i na dole.Używa zmiennej prywatnej. Ta metoda nie wydaje się mieć żadnych problemów w Chrome lub 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 
2

Jeśli masz SelectWeekText i SelectionMode = „DayWeek” lub „DayWeekMonth”, będziesz mieć problemy z markup wybór tygodni nadal pojawiać się na ukrytej tygodnia. Oto jak to zrobiłem z odrobiną 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> 
+0

Dziękujemy! tego właśnie szukałem ze względu na znaczniki wyboru tygodniowego. Musiał dodać (jeśli currDay = 0 Następnie currDay = 7) do funkcji HideExtraWeek, aby zarządzać poniedziałkiem będącym pierwszym dniem tygodnia. Prawdopodobnie nie najczystsze rozwiązanie, ale pracowało dla mnie. – Michelh91

Powiązane problemy