Recently I had a need to add some simple tooltip text to a header of a Gridview. Nothing fancy, just a quick sentence explaining the column headers as they all contained abbreviated text. My searches all turned up overly complex dhtml samples, involving large chunks of JavaScript. These were all fine, but I was really after something a lot more simple than that. It's easy to achieve using some basic HTML with the GridView, so here it is for anyone who wants to do something similar.
After the simple example, I'll show you how you can make things look a little flasher by using Lightbox combined with images instead of mouse over tooltips.
The simple example
As the title says, this is a very simple but dynamic way of achieving tooltip text on a header column. It's not overly flash, but it's lightweight and quick to implement.
First, modify the GridView declaration in to wire up the RowDataBound event:
OnRowDataBound="MyGridView_RowDataBound"
Now in your codebehind, create the RowDataBound method. At this point you need to take into consideration what's actually contained in your header row. If the columns are sortable then the header will contain web controls (Data control link buttons) in order to facilitate the clicking. If they just contain text then there won't be any controls and we can just work with the table cell directly.
First, here's how the method looks if our columns contain text only (non sortable):
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
cell.Attributes.Add("title", "Tooltip text for " + cell.Text);
}
}
}
The idea is that you add a conditional statement in there that checks the value of cell.Text.ToUpper() in order to change the text that is displayed for each cell title, or use an index if that works better for your application.
This works fine for GridViews which don't have any sorting enabled, but as soon as you add AllowSorting="true" to your asp:GridView declaration you'll see it stops working correctly. The code above will still add tooltip text to your cells, but it isn't able to check the contents of cell.Text, because the text is actually placed on controls contained by the cell. Here's how the codebehind can be modified in order to deal with clickable/sortable column headers:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
foreach (Control ctl in cell.Controls)
{
if (ctl.GetType().ToString().Contains("DataControlLinkButton"))
{
cell.Attributes.Add("title", "tooltip text for " + ((LinkButton)ctl).Text);
}
}
}
}
}
Again, add your conditional check on the header/control 'text' by checking the value of ((LinkButton)ctl).Text). The control needs to be cast as a LinkButton, as our loop is set to process all controls in the cell, such as images to indicate the current sorting direction or other visual aids that your application might be using.
That's the simple example done. Told you it was simple. Now lets move on to making things look a little bit more visually interesting by using Lightbox.
Download the Simple Example (15Kb zip file)
The Lightbox example
The Lightbox example allows us to add slicker looking help text to our column headers. They're not really tooltips, because the user does need to click on them before the help image is displayed, however I think it's a nice example of Lightbox in action. It shows how incredibly easy it is to add to any application, as well as how slick it looks.
First, download Lightbox, and follow the setup instructions (add the JavaScript references, the css reference, and the images to your page). Edit lightbox.js if you need to alter the location of the file loading image, or the close image. The sample page contained in the Lightbox archive should help you if you get stuck. I usually add a test link to an image using lightbox to my page first to make sure everything is wired up correctly. Next, create the images containing your help text. Once this is done, we move onto modifying the RowDataBound code - we don't need to make any changes to our asp:GridView declaration at all.
First the code, then a bit of explanation
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
string headerTitle = string.Empty;
foreach (Control ctl in cell.Controls)
{
if (ctl.GetType().ToString().Contains("DataControlLinkButton"))
{
headerTitle = ((LinkButton) ctl).Text.ToUpper();
}
}
Label lbl = new Label();
lbl.Text = " ";
LinkButton lnk = new LinkButton();
lnk.Text = "[?]";
lnk.Attributes["rel"] = "lightbox";
switch(headerTitle)
{
case "TITLE":
lnk.Attributes["href"] = "/Images/tooltip-title.jpg";
lnk.Attributes["title"] = "About the title column";
cell.Controls.Add(lbl);
cell.Controls.Add(lnk);
break;
case "TYPE":
lnk.Attributes["href"] = "/Images/tooltip-type.jpg";
lnk.Attributes["title"] = "About the type column";
cell.Controls.Add(lbl);
cell.Controls.Add(lnk);
break;
case "AUTHOR":
lnk.Attributes["href"] = "/Images/tooltip-author.jpg";
lnk.Attributes["title"] = "About the author column";
cell.Controls.Add(lbl);
cell.Controls.Add(lnk);
break;
default:
break;
}
}
}
}
We're still processing the cells in the Header Row as before, but this time we're adding an additional control to each cell (In my example above I'm actually adding 2 controls, but the label is just a quick way to get some spacing between the column header text and my help link). However we need to add the control outside of the 'foreach (Control ctl in cell.Controls)' loop, because obviously adding an item to a collection we're currently processing isn't a good idea (that is to say it won't work, and will generate the error: Collection was modified; enumeration operation may not execute). So instead, we check the LinkButton's text inside the loop, assign the value to the variable headerTitle, and then add the control outside.
Change the text of the LinkButton to whatever you wish - you could also modify the above example to add an ImageButton with a suitable help graphic which would look a lot tidier. lnk.Attributes["rel"] = "lightbox" is what we need to do to let Lightbox know that we want it to handle the display of this image.
Next we check the headerTitle string which was set previously, and see which control we're adding Help Text for so we can link to the appropriate image. The "title" attribute is optional, if it exists then it is displayed underneath your image as a caption by lightbox. Finally, we add the control(s) to the cell.
..and we're done. Simple as that.
Download the Lightbox Example (129Kb zip file)
The above examples are very simple, but that's the idea. Either of the above methods can be taken much further to provide much more complex solutions, or used as they are for a nice simple and quick solution.
Technorati tags: ASP.NET,
Web Development
Posted on Sunday, April 15, 2007 1:58 PM |