Home   |  Articles   |  Resources   |  Humor   |  Feedback       

  Login   Register 

Ads Via DevMavens


The Calendar Control and the DayRender Event in ASP.Net

Posted by on Sunday, August 22, 2004

Although the ASP.NET Calendar control does not offer a data binding feature, you can customize the content and style of a calendar control using the DayRender event. In this article we combine a Calendar control and a DataGrid control to display a calendar of events.
In this article, we will use the Calendar control and DataGrid controls to display a calendar of events. The calendar will display small icons and highlight each day where an event occurs. When the user selects a date, the grid will show additional details for the events of selected day. A screen shot of the running web form is shown below.

We will first need a source of data. In this example we will use a DataTable, but you should pick what works best for your application. Our web form simulates a database query by populating a DataTable programmatically.

// to simulate a database query
socialEvents = new DataTable();
socialEvents.Columns.Add(new DataColumn("Date", typeof(DateTime)));
socialEvents.Columns.Add(new DataColumn("Description", typeof(string)));
socialEvents.Columns.Add(new DataColumn("Url", typeof(string)));

DataRow row;
row = socialEvents.NewRow();
row["Date"] = DateTime.Now.AddDays(-5);
row["Description"] = "Poker game at Scott's";
row["Url"] = "http://www.OdeToCode.com/blogs/scott/";
socialEvents.Rows.Add(row);
//
// add more rows… 
//

Unlike the DataGrid, the Calendar control has no built in ability to data bind, but the control does allow us to modify the format and content rendered by catching the DayRender event.

The DayRender event fires each time the calendar creates a table cell for the calendar table. The event has an argument of type DayRenderEventArgs. The argument has two properties, one property to represent the date for the cell, and one to represent the TableCell control. Let’s take a look at the event handler for the DayRender event.

private void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
   DataRow[] rows = socialEvents.Select(
         String.Format(
            "Date >= #{0}# AND Date < #{1}#", 
            e.Day.Date.ToShortDateString(),
            e.Day.Date.AddDays(1).ToShortDateString()
         )
      );

   foreach(DataRow row in rows)
   {                         
      System.Web.UI.WebControls.Image image;
      image = new System.Web.UI.WebControls.Image();
      image.ImageUrl = "dot.gif";
      image.ToolTip = row["Description"].ToString();
      e.Cell.Controls.Add(image);
      e.Cell.BackColor = Color.Firebrick;
   }
}

Our first step is to find out if there are any events for the current date. In the above code we are using the DataTable Select method to find matching records, but again you’ll have to adjust the algorithm to suit your application’s performance and scalability requirements. Depending on the size of the data and the number of users you need to support, the Select method may not be the best fit, but it is easy to use for this example.

We need to build a string for the Select expression that will look like the following.

			"Date >= #8/24/2004# AND Date < #8/25/2004#".
		

ADO.NET expressions require dates enclosed within # characters. Comparing dates can be a tricky problem, particularly when the underlying type, like the .NET DateTime type, includes time information. To truncate the time, we use the ToShortDateString method of the DateTime class.

Once we have found valid events, the next step is to modify the appearance of the cell containing the Calendar day. We will add a small icon (dot.gif) for each event by creating an Image control and adding the control to the Cell object’s Controls collection. You can only add static controls, like an Image or HyperLink to the cell, nut not dynamic event raising controls like a DropDownList or Button. We also change the background color of the cell to draw more attention to the date.

When a user selects a date in the Calendar by clicking on a day, the Calendar contol will fire the SelectionChanged event. We can catch this event in our code and display more details for the date selected.

private void Calendar1_SelectionChanged(object sender, System.EventArgs e)
{
   System.Data.DataView view = socialEvents.DefaultView;
   view.RowFilter = String.Format(
                     "Date >= #{0}# AND Date < #{1}#", 
                     Calendar1.SelectedDate.ToShortDateString(),
                     Calendar1.SelectedDate.AddDays(1).ToShortDateString()
                  );
                  
   if(view.Count > 0)
   {
      DataGrid1.Visible = true;
      DataGrid1.DataSource = view;
      DataGrid1.DataBind();
   }
   else
   {
      DataGrid1.Visible = false;
   }
}

In the code above, we again build an expression, but this time for the DataView Filter property. By setting the proper filter expression we can see only those rows in the DataTable matching the selected date. Simple binding this new view of the DataTable to the DataGrid will give us all the details of our events. In the ASPX page we set the DataGrid Visible property to false, and override this property in code only if there are events to display. The columns of the grid are defined as follows.

<Columns>
	<asp:BoundColumn DataField="Description" HeaderText="Description" />
	<asp:HyperLinkColumn DataTextField="Url" HeaderText="Link" NavigateUrl="Url" />
</Columns>

The files Socials.aspx and Socials.aspx.cs are available to download. To experiment with these files, create a new web project in Visual Studio. Right click on the project in the Solution Explorer window and select “Add Existing Item”. Browse to the Socials.aspx file to import the form into the project. This code should give you the basics to try your own calendar control experiments.


Comments:

Need to understand
By odeuser on 10/6/2004
Nice example.

I have couple of questions. For the URL on the DataGrid the link point to http://localhost/Calendar/Url
If I manually add a valid url to the control than the redirection works but it is the same url for all links.
How can we make the title associate to the redirect url?
Is this line suppose to do it or show as a title only:
row["Url"] = "http://www.OdeToCode.com";

What if I want to retrieve data from Access database? How would I populate the current month? Also, what if the user click on the next or previous month can you specify what event or method I would need to use? So if today month is October and the user select next month I would make a query to the database and retrieve data only for November.
If you can specify how to do this in VB.Net it would be better.

Thanks in advance,

Perfect
By rialb86 on 12/1/2004
This is just what i was looking for... Thank you.

VB Version
By jmhmaine on 3/1/2005
I'm trying to adapt this code to VB and receive an error on the have the following:

Dim rows() As DataRow = _dt.Select(String.Format("Date >= #{0}# AND Date < #{1}#", e.Day.Date.ToShortDateString(), e.Day.Date.AddDays(1).ToShortDateString()))

For Each row As DataRow In rows
e.Cell.Text = CType(row("StoryName"), String)
Next

The error is:
Object reference not set to an instance of an object

on the Dim rows() As DataRow line. Thanks.

Copyright 2004 OdeToCode.com 


The Blogs
Subscribe to the OdeToCode blogs for the latest news, downloads, new articles, and quirky commentary.
New Articles
C# 3.0 and LINQ
C# 3.0 introduced a number of new features for LINQ. In this article we'll examine the new features like extension methods, lambda expressions, anonymous types, and more.

Introduction To LINQ
This article is an introduction to LINQ and provides examples of using LINQ to query objects, XML, and relational data.

What ASP.NET Developers Should Know About JavaScript
This article looks at JavaScript from the perspective of a C# or Visual Basic programmer. See how to apply object oriented techniques to your JavaScript code.

Most Popular Articles
Master Pages In ASP.NET 2.0
Master pages in ASP.NET are the key to building a professional web application with a consistent, easy to maintain layout.

ASP.Net 2.0 - Master Pages: Tips, Tricks, and Traps
MasterPages are a great addition to the ASP.NET 2.0 feature set, but are not without their quirks. This article will highlight the common problems developers face with master pages, and provide tips and tricks to use master pages to their fullest potential.

Table Variables In T-SQL
Table variables allow you to store a resultset in SQL Server without the overhead of declaring and cleaning up a temporary table. In this article, we will highlight the features and advantages of the table variable data type.

Contribute Code
Privacy
Consultancy