Can anyone help me with HTMLEncoding a DataGrid?
SUMMARY: HTMLEncoding DataGrid text (whether it requires encoding or not) for any linkbuttons makes them disappear.
As a DataGrid is only used for displaying data in a browser, I would have thought that each DataColumn would have a property for HTMLEncode where, if set to true, would HTMLEncode the data being bound to the grid, and, if set to false, it would display the data as is.
But, no, there is no such property...well, none that I could find anyway.
The solution that I have come up with so far goes part of the way:
1. It uses the DataGrid_ItemDataBound event. This event fires for every TableRow that is bound to the DataGrid.
2. I iterate through each of the cells in the TableRow HTMLEncoding the text as I go.
Now this solution works great for normal BoundColumns. However, for ButtonColumns (and probably HyperlinkColumns and maybe TemplateColumns), HTMLEncoding the text results in the cell/link/button disappearing altogether, leaving nothing for the user to click/push/see/whatever.
Can someone please help me with better solutions to the following workarounds? You will see from the attached code for this event that these workarounds are:
1. Funnily enough, the DataGrid Header & Footer also trigger this event. So the first thing I had to do was to filter out these calls. I would prefer it if I didn't have to do this though because, for a generic solution, there is likely to be a day when I want XML tag-style headers, e.g. "<ID>" instead of just "ID", and I would like these to display.
2. For the moment, my linkbuttons are just for the ID field in my TableGrid. And the ID field is numeric. Therefore, I know that HTMLEncoding the text will have no effect. I therefore do a quick check to see if HTMLEncoding would produce a different result. If it does, I change it. Again, like in 1, there will be a day when I want to display some XML or HTML as a linkbutton.
So, who's up for the challenge :-) ?
ATTACHED CODE - START
/// Event that fires when a DataSet TableRow binds to the DataGrid.
/// It iterates through each cell in the TableRow, ensuring that all
/// the text being displayed is HTML Encoded.
/// <seealso cref="ms-help://MS.VSCC/MS.MSDNVS/cpref/html/frlrfSystemWebUIWebControlsDataGridClassItemDataBoundTopic.htm">DataGrid.ItemDataBound Event</seealso>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dgIssues_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
DataGridItem item = (DataGridItem)e.Item;
ListItemType itemType = item.ItemType;
//Changing the text of the following items makes them disappear
//completely :-( so filter them out here
!( (itemType == ListItemType.Header) ||
(itemType == ListItemType.Footer) ||
(itemType == ListItemType.Pager)
#region TODO [RDavis]
///TODO [RDavis]: Although this next foreach block actually checks
///whether HTML Encoding the DataGrid cell would cause a
///difference, this was only done as a stop-gap measure to stop
///the IssueID hyperlinks disappearing like the Header
///hyperlinks did before I performed the check above.
///Ideally, there should be some way to check what type of
///control is going to be displayed in the DataGrid cell, and
///amend its Text property regardless of whether it would be
///changed or not. This is because it seems that changing the
///Text value of what would be a linkbutton etc seems to make
///it lose the fact that it is going to be a linkbutton etc and
///so decides to be nothing instead (as it wasn't going to be
///plain Text anyway). Unfortunately, it seems (well, from what
///I could find anyway) that the control (and hence its type)
///are not accessible here. I expect that this is because the
///control hasn't yet been created as we're in the middle of a
///databind (and thus about to create the control).
#endregion TODO [RDavis]
TableCellCollection cells = (TableCellCollection)item.Cells;
foreach (TableCell cell in cells)
if (cell.Text != HttpUtility.HtmlEncode(cell.Text.ToString()))
cell.Text = HttpUtility.HtmlEncode(cell.Text.ToString());
ATTACHED CODE - END