Procedura: visualizzare nel controllo Calendar date specifiche ottenute da un database
Aggiornamento: novembre 2007
Il controllo Calendar non supporta direttamente l'associazione dati. In altri termini, non è possibile associare l'intero calendario a un'origine dati. È invece possibile scrivere codice per ottenere i dati necessari e quindi confrontare, nell'evento DayRender, la data correntemente visualizzata con i dati letti da un'origine dati.
Per visualizzare nel controllo Calendar i dati di un database
Utilizzare i tipi ADO.NET per stabilire una connessione a un database ed eseguire una query per ottenere le date da visualizzare.
Nell'evento DayRender del controllo Calendar confrontare la data correntemente visualizzata con i dati recuperati dal database. In caso di corrispondenza, personalizzare la visualizzazione del giorno.
Esempio
Nell'esempio riportato di seguito le informazioni relative alle festività vengono lette da un database e inserite in un DataSet ADO.NET. Le date recuperate si riferiscono al mese corrente, definito come intervallo in base alla proprietà VisibleDate del controllo Calendar, che restituisce la prima data del mese corrente. Ogni volta che l'utente si sposta su un nuovo mese, vengono lette le festività di tale mese. Nell'evento DayRender viene eseguito un confronto tra la data correntemente visualizzata e le date restituite dal database. In caso di corrispondenza, il giorno viene contrassegnato con un colore specifico.
Nota: |
---|
Per utilizzare l'evento DayRender sarà necessario aggiungere la proprietà OnDayRender al markup del controllo di calendario. Ad esempio, il codice potrebbe apparire come segue: |
<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();
}
In questo esempio viene generata una query in base alle date del mese correntemente visualizzato. La proprietà VisibleDate restituisce la prima data del mese corrente. La proprietà VisibleDate non viene impostata finché l'utente non si sposta all'interno del calendario. Di conseguenza, la prima volta che la pagina viene visualizzata, la proprietà VisibleDate viene impostata in base alla selezione dell'utente. Una funzione di supporto inclusa nel codice calcola il primo giorno del mese successivo in base alla proprietà VisibleDate e può pertanto essere utilizzata per generare un intervallo di date nell'ambito del mese corrente.
Compilazione del codice
Nel codice si presuppone che venga utilizzato un database SQL Server contenente la tabella Holidays e che nella tabella sia presente una colonna HolidayDate. La stringa di connessione necessaria per la connessione al database è archiviata nel file Web.config con il nome ConnectionString1.
Nel codice si presuppone inoltre che siano stati importati gli spazi dei nomi System.Data e System.Data.SqlClient, affinché sia possibile utilizzare riferimenti a DataSet, SqlConnection e altri oggetti, anche quando non si tratti di riferimenti completi.
Programmazione efficiente
Quando si esegue una query sul database, racchiudere sempre in un blocco try-catch l'esecuzione della query (in questo esempio, in corrispondenza della chiamata al metodo Fill dell'adattatore dati).