Cómo: Mostrar las fechas seleccionadas de una base de datos en el control Calendar

Actualización: noviembre 2007

El control Calendar no admite directamente el enlace de datos; es decir, no es posible enlazar el calendario como un todo a un origen de datos. En su lugar, debe escribir el código para obtener los datos necesarios y, a continuación, puede comparar la fecha que se está representando en la actualidad con los datos leídos en un origen de datos del evento DayRender.

Para mostrar los datos de la base de datos en el control Calendar

  1. Utilice los tipos de ADO.NET para conectarse con una base de datos y consultar las fechas que se van a mostrar.

  2. En el evento DayRender del control Calendar, compare la fecha que se está representando actualmente con los datos recuperados de la base de datos. Si hay coincidencia, personalice la presentación del día.

Ejemplo

El ejemplo siguiente lee la información de los días festivos de una base de datos en un conjunto de datos de ADO.NET. La selección obtiene las fechas del mes actual, definidas como intervalo basado en la propiedad VisibleDate del control Calendar, que devuelve la primera fecha del mes actual. Cada vez que el usuario se desplaza a un nuevo mes, el código lee los días festivos de ese mes. En el evento DayRender, el código compara la fecha que se está representando actualmente con las fechas devueltas desde la base de datos. Si una fecha coincide, el día se marca con un color especial.

Protected dsHolidays As DataSet

Protected Sub Page_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
        Calendar1.VisibleDate = DateTime.Today
        FillHolidayDataset()
    End If
End Sub

Protected Sub FillHolidayDataset()
    Dim firstDate As New DateTime(Calendar1.VisibleDate.Year, _
         Calendar1.VisibleDate.Month, 1)
    Dim lastDate As DateTime = GetFirstDayOfNextMonth()
    dsHolidays = GetCurrentMonthData(firstDate, lastDate)
End Sub

Protected Function GetFirstDayOfNextMonth() As DateTime
    Dim monthNumber, yearNumber As Integer
    If Calendar1.VisibleDate.Month = 12 Then
        monthNumber = 1
        yearNumber = Calendar1.VisibleDate.Year + 1
    Else
        monthNumber = Calendar1.VisibleDate.Month + 1
        yearNumber = Calendar1.VisibleDate.Year
    End If
    Dim lastDate As New DateTime(yearNumber, monthNumber, 1)
    Return lastDate
End Function

Protected Sub Calendar1_VisibleMonthChanged(ByVal sender As Object, _
        ByVal e As System.Web.UI.WebControls.MonthChangedEventArgs) _
        Handles Calendar1.VisibleMonthChanged
    FillHolidayDataset()
End Sub

Function GetCurrentMonthData(ByVal firstDate As DateTime, _        ByVal lastDate As DateTime) As DataSet
    Dim dsMonth As New DataSet
    Dim cs As ConnectionStringSettings
    cs = ConfigurationManager.ConnectionStrings("ConnectionString1")
    Dim connString As String = cs.ConnectionString
    Dim dbConnection As New SqlConnection(connString)
    Dim query As String
    query = "SELECT HolidayDate FROM Holidays " & _
        " WHERE HolidayDate >= @firstDate AND HolidayDate < @lastDate"
    Dim dbCommand As New SqlCommand(query, dbConnection)
    dbCommand.Parameters.Add(New SqlParameter("@firstDate", firstDate))
    dbCommand.Parameters.Add(New SqlParameter("@lastDate", lastDate))

    Dim sqlDataAdapter As New SqlDataAdapter(dbCommand)
    Try
        sqlDataAdapter.Fill(dsMonth)
    Catch
    End Try
    Return dsMonth
End Function

Protected Sub Calendar1_DayRender(ByVal sender As Object, _
        ByVal e As System.Web.UI.WebControls.DayRenderEventArgs) _
        Handles Calendar1.DayRender
    Dim nextDate As DateTime
    If Not dsHolidays Is Nothing Then
        For Each dr As DataRow In dsHolidays.Tables(0).Rows
            nextDate = CType(dr("HolidayDate"), DateTime)
            If nextDate = e.Day.Date Then
                e.Cell.BackColor = System.Drawing.Color.Pink
            End If
        Next
    End If
End Sub
protected DataSet dsHolidays;

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
    {
        Calendar1.VisibleDate = DateTime.Today;
        FillHolidayDataset();
    }
}

protected void FillHolidayDataset()
{
    DateTime firstDate = new DateTime(Calendar1.VisibleDate.Year, 
        Calendar1.VisibleDate.Month, 1);
    DateTime lastDate = GetFirstDayOfNextMonth();
    dsHolidays = GetCurrentMonthData(firstDate, lastDate);
}

protected DateTime GetFirstDayOfNextMonth()
{
    int monthNumber, yearNumber;
    if(Calendar1.VisibleDate.Month == 12)
    {
        monthNumber = 1;
        yearNumber = Calendar1.VisibleDate.Year + 1;
    }
    else
    {
        monthNumber = Calendar1.VisibleDate.Month + 1;
        yearNumber = Calendar1.VisibleDate.Year;
    }
    DateTime lastDate = new DateTime(yearNumber, monthNumber, 1);
    return lastDate;
}

protected DataSet GetCurrentMonthData(DateTime firstDate, 
     DateTime lastDate)
{
    DataSet dsMonth = new DataSet();
    ConnectionStringSettings cs;
    cs = ConfigurationManager.ConnectionStrings["ConnectionString1"];
    String connString = cs.ConnectionString;
    SqlConnection dbConnection = new SqlConnection(connString);
    String query;
    query = "SELECT HolidayDate FROM Holidays " + _
        " WHERE HolidayDate >= @firstDate AND HolidayDate < @lastDate";
    SqlCommand dbCommand = new SqlCommand(query, dbConnection);
    dbCommand.Parameters.Add(new SqlParameter("@firstDate", 
        firstDate));
    dbCommand.Parameters.Add(new SqlParameter("@lastDate", lastDate));

    SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(dbCommand);
    try
    {
        sqlDataAdapter.Fill(dsMonth);
    }
    catch {}
    return dsMonth;
}

protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
    DateTime nextDate;
    if(dsHolidays != null)
    {
     foreach(DataRow dr in dsHolidays.Tables[0].Rows)
     {
            nextDate = (DateTime) dr["HolidayDate"];
            if(nextDate == e.Day.Date)
            {
                e.Cell.BackColor = System.Drawing.Color.Pink;
            }
     }
    }
}
protected void Calendar1_VisibleMonthChanged(object sender, 
    MonthChangedEventArgs e)
{
    FillHolidayDataset();
}

Este ejemplo genera una consulta que se basa en las fechas del mes que se muestra actualmente. La propiedad VisibleDate devuelve la primera fecha del mes actual. (No se establece la propiedad VisibleDate hasta que el usuario se desplace por el calendario. De esta forma, la primera vez que se muestra la página, el código establece la propiedad VisibleDate manualmente.) Una función auxiliar del código calcula el primer día del mes siguiente en función del valor de la propiedad VisibleDate y, por tanto, se puede utilizar para generar un intervalo de fechas en el mes actual.

Compilar el código

El código asume que se está utilizando una base de datos de SQL Server con la tabla Holidays. La tabla tiene la columna HolidayDate. La cadena de conexión necesaria para establecer conexión con la base de datos se almacena en el archivo Web.config debajo del nombre ConnectionString1.

El código asume que se han importado los espacios de nombres System.Data y System.Data.SqlClient para que se puedan utilizar las referencias a DataSet, SqlConnection y a otros objetos sin que aparezcan los nombres completos.

Programación eficaz

Al consultar la base de datos, siempre debe incluir la ejecución de la consulta (en este ejemplo, al llamar al método Fill del adaptador de datos) en un bloque try-catch.

Vea también

Conceptos

Información general sobre Calendar (Control de servidor Web)