J
John Wallace
Hi,
Sorry for the long message - most of it is a code example Quite a
quick question really!
I'm having a problem (possibly found a bug) while trying to implement
a template column in an ASP.NET Datagrid.
The grid will list files on the local file system, one row per file.
The column itself contains a single checkbox per row
which I want to reference in dynamically generated client script.
The problem is that the "Checkbox.ClientID" I get when building the
script on the server is NOT the one that is eventually rendered on the
client and the script fails with "object not found".
A quick sample of my code is:
===================================================================
public class MyCheckboxColumnTemplate : ITemplate, INamingContainer
{
....local vars...
....constructor...
public void InstantiateIn(System.Web.UI.Control container)
{
switch(Template Type)
{
...
case ListItemType.Item:
CheckBox cb = new CheckBox();
cb.DataBinding += new EventHandler(this.BindCheckboxColumn);
container.Controls.Add(cb);
break;
...
}
}
public void BindCheckboxColumn(object sender, EventArgs e)
{
CheckBox objCheckBox = (CheckBox)sender;
DataGridItem container = (DataGridItem)objCheckBox.NamingContainer ;
bool bIsSelected = Convert.ToBoolean(DataBinder.Eval(((DataGridItem)container).DataItem,
"RowSelected")); //from the underlying dataset
objCheckBox.Checked = bIsSelected;
objCheckBox.Attributes.Add("onclick","alert(document.all(\"" +
objCheckBox.ClientID + "\").checked)"); //THIS CLIENTID IS "WRONG".
}
}
Then in the Datagrid processing...
private void FileManagerGrid_ItemDataBound(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
...
if (e.Item.ItemType != ListItemType.Header && e.Item.ItemType !=
ListItemType.Footer)
{
e.Item.ID = e.Item.Cells[FILE_MANAGER_COLUMN_FILENAME].Text; //Set
the ID of the row to the filename it represents
...
}
...
}
===================================================================
All this results in rendered HTML table rows, as follows (line numbers
for reference):
....
1 <tr id="PageName1_FileManagerGrid_FILENAME1.EXT"
onclick="FileManagerTRClick(this, 'FILENAME1.EXT');"> //onclick call
custom generated
2 <td>
3 <span onclick="alert(document.all("PageName1_FileManagerGrid__ctl2_RowSelected").checked)">
4 <input id="PageName1_FileManagerGrid_FILENAME1.EXT_RowSelected"
type="checkbox" name="PageName1_FileManagerGrid_FILENAME1.EXT_RowSelected"
/>
5 </span>
6 </td>
7 <td>FILENAME1.EXT</td>
8 </tr>
....
The "alert" on line 3 is from the attribute added in
"BindCheckboxColumn" above. You can see that the Checkbox.ClientID
gave the value "PageName1_FileManagerGrid__ctl2_RowSelected" to
reference the control,
however the checkbox (input) control actually has the ID
"PageName1_FileManagerGrid_FILENAME1.EXT_RowSelected".
It seems that the ClientID for the checkbox did not correctly inherit
the IDs from the parent objects while processing on the server, but
did inherit it when the HTML was sent to the browser!
Has anyone seen this? Any workarounds or obvious things I'm missing
here?
Thanks,
John
Sorry for the long message - most of it is a code example Quite a
quick question really!
I'm having a problem (possibly found a bug) while trying to implement
a template column in an ASP.NET Datagrid.
The grid will list files on the local file system, one row per file.
The column itself contains a single checkbox per row
which I want to reference in dynamically generated client script.
The problem is that the "Checkbox.ClientID" I get when building the
script on the server is NOT the one that is eventually rendered on the
client and the script fails with "object not found".
A quick sample of my code is:
===================================================================
public class MyCheckboxColumnTemplate : ITemplate, INamingContainer
{
....local vars...
....constructor...
public void InstantiateIn(System.Web.UI.Control container)
{
switch(Template Type)
{
...
case ListItemType.Item:
CheckBox cb = new CheckBox();
cb.DataBinding += new EventHandler(this.BindCheckboxColumn);
container.Controls.Add(cb);
break;
...
}
}
public void BindCheckboxColumn(object sender, EventArgs e)
{
CheckBox objCheckBox = (CheckBox)sender;
DataGridItem container = (DataGridItem)objCheckBox.NamingContainer ;
bool bIsSelected = Convert.ToBoolean(DataBinder.Eval(((DataGridItem)container).DataItem,
"RowSelected")); //from the underlying dataset
objCheckBox.Checked = bIsSelected;
objCheckBox.Attributes.Add("onclick","alert(document.all(\"" +
objCheckBox.ClientID + "\").checked)"); //THIS CLIENTID IS "WRONG".
}
}
Then in the Datagrid processing...
private void FileManagerGrid_ItemDataBound(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
...
if (e.Item.ItemType != ListItemType.Header && e.Item.ItemType !=
ListItemType.Footer)
{
e.Item.ID = e.Item.Cells[FILE_MANAGER_COLUMN_FILENAME].Text; //Set
the ID of the row to the filename it represents
...
}
...
}
===================================================================
All this results in rendered HTML table rows, as follows (line numbers
for reference):
....
1 <tr id="PageName1_FileManagerGrid_FILENAME1.EXT"
onclick="FileManagerTRClick(this, 'FILENAME1.EXT');"> //onclick call
custom generated
2 <td>
3 <span onclick="alert(document.all("PageName1_FileManagerGrid__ctl2_RowSelected").checked)">
4 <input id="PageName1_FileManagerGrid_FILENAME1.EXT_RowSelected"
type="checkbox" name="PageName1_FileManagerGrid_FILENAME1.EXT_RowSelected"
/>
5 </span>
6 </td>
7 <td>FILENAME1.EXT</td>
8 </tr>
....
The "alert" on line 3 is from the attribute added in
"BindCheckboxColumn" above. You can see that the Checkbox.ClientID
gave the value "PageName1_FileManagerGrid__ctl2_RowSelected" to
reference the control,
however the checkbox (input) control actually has the ID
"PageName1_FileManagerGrid_FILENAME1.EXT_RowSelected".
It seems that the ClientID for the checkbox did not correctly inherit
the IDs from the parent objects while processing on the server, but
did inherit it when the HTML was sent to the browser!
Has anyone seen this? Any workarounds or obvious things I'm missing
here?
Thanks,
John