2010-03-25 14 views
6

No estoy seguro de por qué otras personas no han preguntado esto antes. Pero ¿has notado que el asp: Calendario muestra una semana extra al final?Cómo quitar la última semana de un calendario

Por ejemplo, si VisibleMonth está configurado para 2010-03-01 y FirstDayOfWeek para Sunday: Se mostrarán 6 semanas.

  1. 28 febrero-6 marzo
  2. 7 marzo hasta 13 marzo
  3. 14 marzo-20 marzo
  4. 21 marzo a 27 marzo
  5. 28 marzo-3 abril
  6. 4 abril hasta abril 10

Me preguntaba por qué Microsoft muestra la última fila, que es totalmente en abril. Traté de buscar en la red una propiedad pero parece que no existe.

La única solución que podía pensar es anular el Pre_Render y verificar todas las fechas individuales si todavía están dentro de la semana del VisibleDate. Pero, por supuesto, es una comprobación extrema ya que cada renderización del control lo muestra.

Aquí está mi trabajo.

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

Respuesta

7

muy bonito. Funciona con la mayoría de los navegadores pero es frágil con Chrome 11.0.696.71 y Safari para Windows (no se ha probado en mac)

Durante algunos meses, el control de calendario muestra la semana adicional al principio del mes. (cuando el primer día del mes es el primer día de la semana)

Cuando configura e.cell.Visible = false, no representa los elementos. Entonces en Chrome terminas con una fila <tr></tr>. Chrome lo muestra como una fila en blanco. Y dado que no creo que haya una manera de establecer la altura/estilo del elemento TR a través del control de calendario, terminas con un calendario de aspecto feo al que le falta su primera fila para ciertos meses.

Establecer también la altura en 0 no hace nada cuando establece Visible = false. Si no establece Visible = falso y simplemente pone height = 0, todavía no se procesa correctamente en chrome. Entonces la solución es establecer la altura en

Aquí está mi solución modificada.

la onrowrender

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

la función

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 tengo otra solución. Después de algunos ajustes. Espero que ayude Tiene un poco más de funciones, pero si tu calendario obtiene muchos éxitos, puede que solo guarde un 1% de cpu :). Asegúrese de adjuntar el evento Calendar1_VisibleMonthChanged a 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

Aquí está el código VB yo uso. Eliminará las filas vacías en la parte superior e inferior cuando sea necesario.Utiliza una variable privada. Este método no parece tener ningún problema en Chrome o 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

Si tiene SelectWeekText y SelectionMode = "DayWeek" o "DayWeekMonth", tendrá problemas con el marcado selección semanas sigue mostrando para la semana escondido. Así es como lo hice con un poco de 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

¡Gracias! esto es lo que estaba buscando debido al margen de selección de la semana. Tuve que agregar (si currDay = 0 Then currDay = 7) a la función HideExtraWeek para administrar el lunes como el primer día de la semana. Probablemente no sea la solución más limpia, pero funcionó para mí. – Michelh91

Cuestiones relacionadas