방법: Calendar 컨트롤에서 데이터베이스의 선택된 날짜 표시

업데이트: 2007년 11월

Calendar 컨트롤은 데이터 바인딩을 직접 지원하지 않습니다. 즉, 달력 전체를 데이터 소스에 바인딩하면 안 됩니다. 대신 필요한 데이터를 가져오는 코드를 작성한 다음 DayRender 이벤트에서 현재 렌더링된 날짜와 데이터 소스에서 읽은 데이터를 비교할 수 있습니다.

Calendar 컨트롤에서 데이터베이스 데이터를 표시하려면

  1. ADO.NET 형식을 사용하여 데이터베이스에 연결하고 표시할 날짜를 쿼리합니다.

  2. Calendar 컨트롤의 DayRender 이벤트에서 현재 렌더링된 날짜와 데이터베이스에서 가져온 데이터를 비교합니다. 일치하는 항목이 있으면 날짜 표시를 사용자 지정합니다.

예제

다음 예제에서는 데이터베이스의 공휴일 정보를 ADO.NET 데이터 집합으로 읽어 옵니다. 현재 달의 첫 번째 날짜를 반환하는 Calendar 컨트롤의 VisibleDate 속성에 따라 범위로 정의된 현재 달의 날짜를 가져옵니다. 이 코드에서는 사용자가 새 달로 이동할 때마다 해당 달의 공휴일을 읽어 옵니다. DayRender 이벤트의 코드는 현재 렌더링된 날짜와 데이터베이스에서 반환된 날짜를 비교합니다. 일치하는 날짜는 특수 색으로 표시됩니다.

참고:

DayRender 이벤트를 사용하기 위해 Calendar 컨트롤 태그에 OnDayRender 속성을 추가해야 합니다. 예를 들어 코드는 다음 코드 예제와 같습니다.

<asp:Calendar id="Calendar1" OnDayRender=" Calendar1_DayRender"  ></asp:Calendar>
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();
}

이 예제에서는 현재 표시된 달의 날짜를 기준으로 쿼리를 만듭니다. VisibleDate 속성은 현재 달의 첫 번째 날짜를 반환합니다. VisibleDate 속성은 사용자가 달력에서 이동하기 전까지는 설정되지 않으므로 페이지가 처음 표시될 때는 코드에서 VisibleDate 속성을 수동으로 설정합니다. 코드의 도우미 함수는 VisibleDate 속성을 기준으로 다음 달의 첫 번째 날짜를 계산하므로 현재 달의 날짜 범위를 만드는 데 사용될 수 있습니다.

코드 컴파일

이 코드에서는 Holidays 테이블이 들어 있는 SQL Server 데이터베이스를 사용하는 것으로 가정합니다. 이 테이블에는 HolidayDate 열이 있습니다. 데이터베이스에 연결하는 데 필요한 연결 문자열은 Web.config 파일의 ConnectionString1 이름 아래에 저장되어 있습니다.

또한 이 코드에서는 DataSet, SqlConnection 및 다른 개체에 대한 참조를 완전히 한정하지 않고도 사용할 수 있도록 System.DataSystem.Data.SqlClient 네임스페이스를 가져왔다고 가정합니다.

강력한 프로그래밍

데이터베이스를 쿼리할 때는 항상 쿼리 실행 코드(이 예제에서는 데이터 어댑터의 Fill 메서드를 호출하는 코드)를 try-catch 블록에 포함시켜야 합니다.

참고 항목

개념

Calendar 웹 서버 컨트롤 개요