方法 : データベースで選択した日付を Calendar コントロールに表示する
更新 : 2007 年 11 月
Calendar コントロールはデータ バインディングを直接サポートしていません。つまり、カレンダー全体を 1 つのデータ ソースにバインドすることはありません。代わりに、必要なデータを取得するコードを記述し、現在表示されている日付とデータ ソースから読み取ったデータを DayRender イベントで比較します。
データベースのデータを Calendar コントロールに表示するには
ADO.NET 型を使用してデータベースに接続し、表示する日付を照会します。
Calendar コントロールの DayRender イベントで、現在表示されている日付をデータベースから取得したデータと比較します。一致する日付がある場合は、日の表示をカスタマイズします。
使用例
次の例では、データベースの休日情報を ADO.NET データセットに読み込みます。選択項目から、Calendar コントロールの VisibleDate プロパティに基づく範囲として定義された現在の月の日付が取得されます。このプロパティは、現在の月の最初の日付を返します。ユーザーが新しい月に移動するたびに、その月の休日が読み込まれます。DayRender イベントでは、現在表示されている日付とデータベースから返された日付が比較されます。日付が一致した場合、その日は特別な色でマークされます。
メモ : |
---|
DayRender イベントを利用するには、Calendar コントロール マークアップに OnDayRender プロパティを追加する必要があります。たとえば、次のようなコードになります。 |
<asp:Calendar id="Calendar1" OnDayRender=" Calendar1_DayRender" runat="server" ></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 列があります。データベースに接続するために必要な接続文字列は、ConnectionString1 という名前で Web.config ファイルに格納されます。
このコードは、DataSet、SqlConnection、およびその他のオブジェクトへの参照を完全修飾せずに使用できるように、名前空間 System.Data および System.Data.SqlClient がインポート済みであることを想定しています。
堅牢性の高いプログラム
データベースを照会するときは、必ずクエリの実行 (この例では、データ アダプタの Fill メソッドを呼び出すとき) を try-catch ブロックで囲みます。