2008-11-04 6 views
5

Le calendrier ASP.NET affiche toujours 6 semaines de dates dans une grille 7x6. Mon problème est que le premier jour du mois cible pas nécessairement apparaissent dans la première rangée ... dans certains cas, toute la première rangée affiche les dates du mois précédent. Dans d'autres cas, toute la dernière ligne affiche les dates de la ligne suivante. Existe-t-il un moyen fiable d'interroger l'objet de calendrier pour déterminer la plage de 42 jours qui serait restituée pour un mois/une année spécifique?Comment déterminer toute la plage de dates affichée par le calendrier ASP.NET?

Par exemple, considérons Juin 2008 et février 2009:

Notice that the first week contains ONLY dates from prior month http://img371.imageshack.us/img371/2290/datesmq5.png

Je suppose que le calendrier essaie d'éviter bottelage toutes les dates « autres mois » soit en haut ou en bas de la grille, et met donc le premier du mois cible sur la 2e rangée. Je cherche un moyen facile de déterminer que la plage affichée pour Juin 2008 est le 25 mai - 5 Juillet, par exemple.

Répondre

5

En regardant les membres publics exposés par le contrôle du calendrier ASP.NET je ne crois pas que cette information est quelque chose que vous pouvez simplement obtenir à partir du contrôle du calendrier.

Vous avez quelques options comme "solutions de contournement" à cela, bien que pas agréable .... mais ils fonctionneraient.

  1. Vous pouvez manuellement calculer les valeurs de la première semaine
  2. Vous pouvez gérer l'événement « jour rendre » pour gérer la liaison des jours individuels, et enregistrer des valeurs min/max.

Certes ni est élégant, mais il est AFAIK la seule véritable option

Modifier

Après discussion dans les commentaires, une autre option est une version modifiée de mon deuxième option ci-dessus. Fondamentalement, la première fois que Day Render est appelé, obtenez le bloc de données pour les 42 prochains jours, puis vous pouvez simplement rechercher dans la liste la valeur du jour à afficher sur les prochains appels à DayRender, évitant un hit DB pour chaque jour. Faire ceci est une autre solution "non-élégante", mais cela fonctionne, et réduit un peu de charge sur la DB, mais introduit une certaine surcharge du côté de l'application.

Il est important ici de bien définir structurés propriétés de niveau de la page pour contenir les éléments pendant les événements de liaison, mais pour faire en sorte que si un mois a changé, etc qu'il n'a pas été chargé de manière incorrecte, etc.

+0

La chose est, je dois connaître la gamme qui sera rendue avant que je puisse obtenir des données de mon niveau de données, donc l'utilisation DayRender est pas une option. Je vais probablement faire # 1, bien que je déteste l'idée d'essayer de désosser l'algorithme nécessaire ... semble très enclin à l'erreur. Merci quand même! –

+0

Y at-il une raison pour laquelle vous ne pouvez pas faire un appel dB sur dayrender pour obtenir les données exactes dont vous avez besoin? –

+0

@Mitchel: Cela entraînerait un hit DB distinct pour chaque jour. Je préférerais déterminer la plage de dates qui sera affichée et ensuite obtenir toutes ces données, rien de plus et rien de moins, dans un seul appel DB. –

2

Mitchel, A travaillé parfaitement, merci. commencé avec un variable publique bool m_FirstDay = false

dans la fonction day_render

if(m_FirstDay == false) 
{ 
    DateTime firstDate; 
    DateTime lastDate; 

    firstDate = e.Day.Date; 
    lastDate = firstDate.AddDays(41); 

    m_FirstDay = true; 
} 

j'avais alors la plage de dates visible du contrôle du calendrier asp.net. Merci encore.

5

J'ai écrit quelques méthodes pour vous aider. Il suffit de passer dans Calendar.VisibleDate:

public static DateTime GetFirstDateOfMonth(DateTime date) 
{ 
    return new DateTime(date.Year, date.Month, 1); 
} 

public static DateTime GetFirstDisplayedDate(DateTime date) 
{ 
    date = GetFirstDateOfMonth(date); 
    return date.DayOfWeek == DayOfWeek.Sunday ? date.AddDays(-7) : date.AddDays((int)date.DayOfWeek * -1); 
} 

public static List<DateTime> GetDisplayedDates(DateTime date) 
{ 
    date = GetFirstDisplayedDate(date); 

    List<DateTime> dates = new List<DateTime>(); 
    for (int i = 0; i < 42; i++) 
    { 
     dates.Add(date.AddDays(i)); 
    } 

    return dates; 
} 
+0

J'aime cette solution, seule celle-ci ne tient pas compte des différentes cultures. Voir [link] http://joelabrahamsson.com/getting-the-first-day-in-a-week-with-c/ [/ link] pour obtenir la première date d'une semaine étant donné le GetFirstDateOfMonth. –

2

Je viens juste de me pencher là-dessus, et j'ai été dirigé vers ici.Je suis personnellement tenté d'aller avec l'option deux, parce que l'alternative est désordonnée. La version de Ronnie est sympa, mais ne prend malheureusement pas en compte les cultures avec des FirstDayOfWeeks différentes.

utilisant réflecteur, nous pouvons voir comment cela se fait en interne:


    ... 
    DateTime visibleDate = this.EffectiveVisibleDate(); 
    DateTime firstDay = this.FirstCalendarDay(visibleDate); 
    ... 

private System.Globalization.Calendar threadCalendar = 
    DateTimeFormatInfo.CurrentInfo.Calendar; 

private DateTime EffectiveVisibleDate() 
{ 
    DateTime visibleDate = this.VisibleDate; 
    if (visibleDate.Equals(DateTime.MinValue)) 
    { 
     visibleDate = this.TodaysDate; 
    } 
    if (this.IsMinSupportedYearMonth(visibleDate)) 
    { 
     return this.minSupportedDate; 
    } 
    return this.threadCalendar.AddDays(visibleDate, 
     -(this.threadCalendar.GetDayOfMonth(visibleDate) - 1)); 
} 


private DateTime FirstCalendarDay(DateTime visibleDate) 
{ 
    DateTime date = visibleDate; 
    if (this.IsMinSupportedYearMonth(date)) 
    { 
     return date; 
    } 
    int num = ((int) 
     this.threadCalendar.GetDayOfWeek(date)) - this.NumericFirstDayOfWeek(); 
    if (num <= 0) 
    { 
     num += 7; 
    } 
    return this.threadCalendar.AddDays(date, -num); 
} 

private int NumericFirstDayOfWeek() 
{ 
    if (this.FirstDayOfWeek != FirstDayOfWeek.Default) 
    { 
     return (int) this.FirstDayOfWeek; 
    } 
    return (int) DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek; 
} 

private bool IsMinSupportedYearMonth(DateTime date) 
{ 
    return this.IsTheSameYearMonth(this.minSupportedDate, date); 
} 

private bool IsTheSameYearMonth(DateTime date1, DateTime date2) 
{ 
    return (((this.threadCalendar.GetEra(date1) == 
        this.threadCalendar.GetEra(date2)) && 
      (this.threadCalendar.GetYear(date1) == 
        this.threadCalendar.GetYear(date2))) && 
      (this.threadCalendar.GetMonth(date1) == 
        this.threadCalendar.GetMonth(date2))); 
} 

Malheureusement, la fonctionnalité est déjà là, nous ne pouvons pas nous mettre au travail!

Questions connexes