“A goal is a dream with a finish line.” --Duke Ellington
A frequent request I've seen here and elsewhere in my travels is the ability to add "tooltips" to various ASP.NET controls. There are a number of solutions to this, usually involving some heavy-duty Javacript, but so far I have never seen the one solution that to me is so obvious: Add a TITLE attribute!
First, let's look at the definition of this attribute:
title
Description
Specifies advisory information for the element.
Remarks
Internet Explorer 4.0 renders the title as a ToolTip when the user hovers the mouse over the element.
This property has read-write permissions and takes a string.
Syntax
object.title[ = "sMyString"]
Applies To:
A, ACRONYM, ADDRESS, APPLET, AREA, B, BASE, BASEFONT, BGSOUND, BIG, BLOCKQUOTE, BODY, BR, BUTTON, CAPTION, CENTER, CITE, CODE, COL, COLGROUP, COMMENT, DD, DEL, DFN, DIR, DIV, DL, DT, EM, EMBED, FIELDSET, FONT, FORM, FRAME, FRAMESET, H1, H2, H3, H4, H5, H6, HEAD, HR, I, IFRAME, IMG, INPUT, INS, KBD, LABEL, LEGEND, LI, LISTING, MAP, MARQUEE, MENU, META, NEXTID, OBJECT, OL, OPTION, P, PLAINTEXT, PRE, Q, S, SAMP, SCRIPT, SELECT, SMALL, SPAN, STRIKE, STRONG, SUB, SUP, TABLE, TBODY, TD, TEXTAREA, TFOOT, TH, THEAD, TITLE, TR, TT, U, UL, VAR, XMP
As we can see in the "Applies To" list of element names, you can stick a TITLE Attribute on just about ANYTHING! So how would we go about adding a TITLE attribute to a cell in a DataGrid? The answer is ItemDataBound. This event fires for every row that is added to a DataGrid control during DataBinding. First, let's look at what this sample grid looks like in the HTML (ASPX) declarative tag portion of the page:
<asp:DataGrid id="DataGrid1" style="Z-INDEX: 101; LEFT: 288px; POSITION: absolute; TOP: 152px"
runat="server" BorderColor="#CC9966" BorderStyle="None" BorderWidth="1px" BackColor="White"
CellPadding="4" AutoGenerateColumns="False">
<SelectedItemStyle Font-Bold="True" ForeColor="#663399" BackColor="#FFCC66"></SelectedItemStyle>
<ItemStyle ForeColor="#330099" BackColor="White"></ItemStyle>
<HeaderStyle Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000"></HeaderStyle>
<FooterStyle ForeColor="#330099" BackColor="#FFFFCC"></FooterStyle>
<Columns>
<asp:BoundColumn DataField="pubDate" HeaderText="pubDate"></asp:BoundColumn>
<asp:HyperLinkColumn DataNavigateUrlField="link" DataTextField="title" HeaderText="Title" NavigateUrl="link"></asp:HyperLinkColumn>
</Columns>
<PagerStyle HorizontalAlign="Center" ForeColor="#330099" BackColor="#FFFFCC"></PagerStyle>
</asp:DataGrid> |
All I did above was design two columns. First is a text column assigned to the pubDate field of the datasource, and the other is a Hyperlink column with its DataNavigateUrl field assigned to the "link" column of the Data Source, and its "DataTextField" assigned to the "title" column of the Data Source. You'll see in a moment that I am populating the underlying DataSet using the ReadXml method of the DataSet class pointed to our main eggheadcafe.com RSS feed. Boy, that's an easy way to get a DataSet out of thin air! Now let's take a look at the codebehind and what's required to add a TITLE attribute to each "LINK" column in the grid as it is DataBound:
using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace EasyDataGridToolTips
{
public class WebForm1 : Page
{
protected DataGrid DataGrid1;
private DataSet ds;
private void Page_Load(object sender, EventArgs e)
{
ds = new DataSet();
ds.ReadXml("http://www.nullskull.com/rss.xml");
this.DataGrid1.DataSource=ds.Tables[2];
DataGrid1.DataBind();
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.DataGrid1.ItemDataBound += new DataGridItemEventHandler(this.DataGrid1_ItemDataBound);
this.Load += new EventHandler(this.Page_Load);
}
#endregion
private void DataGrid1_ItemDataBound(object sender, DataGridItemEventArgs e)
{
int i = e.Item.DataSetIndex;
ListItemType it = e.Item.ItemType;
if(it == ListItemType.Item || it == ListItemType.AlternatingItem)
{
string strB = (string)ds.Tables[2].Rows[i]["description"];
e.Item.Attributes.Add("title", strB);
}
}
}
}
And the result should look something like this on a mouseover:
You can see that when you pull an RSS feed directly into a DataSet, the "Items" aggregate normally turns out to be Table "2" - the third table in the DataSet. I hope this little exercise has been useful to you.
Download the Visual Studio.NET 2003 Solution that accompanies this article
|