I've come up with a pretty good solution to the problem of needing to build
the NavigateUrl using multiple data values. My solution is partially based
on code from this article:
http://tripleasp.net/tutorial.aspx?NavID=27
You need to use a TemplateColumn instead of a HyperLinkColumn. But in order
to build a TemplateColumn dynamically, you need a class that implements
ITemplate. I've created such a class which I feel solves this problem quite
nicely.
Using the class is as simple as:
TemplateColumn linkCol = new TemplateColumn();
linkCol.ItemTemplate = new MultiSourceHyperLinkTemplate("orderItemName",
"ShowItem.aspx?order={0}&item={1}",
new string[]{"orderNumber", "orderItemNumber"});
DataGrid1.Columns.Add(linkCol);
The above example assumes that orderItemName, orderNumber, and
orderItemNumber are all column names in the datasource for the datagrid.
The majority of the work is done by the MultiSourceHyperLinkTemplate class,
defined below:
public class MultiSourceHyperLinkTemplate : System.Web.UI.ITemplate
{
string m_DataTextField;
string m_DataNavigateUrlFormatString;
string[] m_DataNavigateUrlFields;
public MultiSourceHyperLinkTemplate(string dataTextField, string
navigateUrlFormatString, string[] navigateUrlFields)
{
m_DataTextField = dataTextField;
m_DataNavigateUrlFormatString = navigateUrlFormatString;
m_DataNavigateUrlFields = navigateUrlFields;
}
private void BindData(object sender, EventArgs e)
{
HyperLink link = (HyperLink) sender;
DataGridItem container = (DataGridItem) link.NamingContainer;
DataRowView curRow = (DataRowView) container.DataItem;
link.Text = curRow[m_DataTextField].ToString();
// evaluate each of the data fields
string[] navigateUrlValues = new string[m_DataNavigateUrlFields.Length];
for (int i = 0; i < m_DataNavigateUrlFields.Length; ++i)
navigateUrlValues
= curRow[m_DataNavigateUrlFields].ToString();
link.NavigateUrl =
String.Format(System.Globalization.CultureInfo.InvariantCulture,
m_DataNavigateUrlFormatString, navigateUrlValues);
}
#region ITemplate Members
public void InstantiateIn(System.Web.UI.Control container)
{
HyperLink link = new HyperLink();
link.DataBinding += new EventHandler(BindData);
container.Controls.Add(link);
}
#endregion
#region Property accessors
string DataTextField { get { return m_DataTextField; } set {
m_DataTextField = value; } }
string DataNavigateUrlFormatString { get { return
m_DataNavigateUrlFormatString; } set { m_DataNavigateUrlFormatString =
value; } }
string[] DataNavigateUrlFields { get { return m_DataNavigateUrlFields; }
set { m_DataNavigateUrlFields = value; } }
#endregion
}
Enjoy!
-Joshua Flanagan