Problem accessing control's ClientID on ASP.NET ListView's ItemCreated - by Panya

Status : 

  Won't Fix<br /><br />
		Due to several factors the product team decided to focus its efforts on other items.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.


3
0
Sign in
to vote
ID 328680 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 2/14/2008 7:06:14 PM
Access Restriction Public

Description

On any ASP.NET ListView's ItemCreated event.
If one trying to access "ClientID" property of a certain control 
inside ListView's InsertItemTemplate.
The actual client ID of that control, when it is rendered into HTML, will be corrupted
and hence the postback of that control won't fire any event 
or the data cannot be bound.
Sign in to post a comment.
Posted by Microsoft on 2/19/2008 at 4:11 PM
Thanks for reporting this issue. There is a bug in how System.Web.UI.Control caches its UniqueID if it has been accessed before its NamingContainer has been added to the control tree. This is exactly the bug you are seeing -- your custom control accesses its UniqueID property before its parent GenericWebPart (a NamingContainer) has been added to the control tree.

Unfortunately, due to performance and compatibility concerns, we are unable to fix the root cause of this issue in System.Web.UI.Control. Here are the workaround that may help your scenario:

Your current code:

protected void ListView1_ItemCreated(object sender, ListViewItemEventArgs e) {
if (e.Item.ItemType == ListViewItemType.InsertItem) {
     TextBox TextBox1 = (TextBox)e.Item.FindControl("FirstNameTextBox");
     if (TextBox1 != null) {
    string s = TextBox1.ClientID;            
    <<< Error: accessing ClientID here as too early in the page lifecycle
     }
}



To solve this problem:

1. If possible, access ClientID in DataBound event:
e.g.
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e) {
if (e.Item.ItemType == ListViewItemType.DataItem) {
    Label label1 = (Label)e.Item.FindControl("FirstNameLabel");
    if (label1 != null) {
     string s = label1.ClientID;
     <<< Accessing ClientID is GOOD.
    }
}

2. It is also good to access the FindControl and access ClientID at PreRender

e.g.

public static Control FindControl(string controlId, ControlCollection controls) {
foreach (Control control in controls) {
    if (control.ID == controlId)
     return control;
    if (control.HasControls()) {
     Control nestedControl = FindControl(controlId, control.Controls);
     if (nestedControl != null)
        return nestedControl;
     }
}
return null;
}

protected void ListView1_PreRender(object sender, EventArgs e) {
        
Label label = FindControl("FirstNameLabel", ListView1.Controls) as Label;

if (label != null) {
    string s = label.ClientID;
    <<<< good to access from here
    }
}

**** NOTE: In ASP.NET 2.0 the page hierarchy often happens to be deeper than it was with the older version. Consequently, when you want to obtain a reference to a control of the page given its ID and you don't know at which level of the hierarchy it is placed, using the FindControl() method of the Page object isn't the right way of proceding since it just performs a search among the direct children of the page itself. In such cases you may use a recursive search as shown above.

3. FindControl an access ClientID in Page_Load
e.g.
protected void Page_Load(object sender, EventArgs e) {
Label label = FindControl("FirstNameLabel", ListView1.Controls) as Label;
if (label != null) {
    string s = label.ClientID;
<<< also GOOD to access from here
}
}


Hope this helps.
Posted by Microsoft on 2/14/2008 at 11:03 PM
Thanks for your feedback. We are escalating this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you,
Visual Studio Product Team
Posted by Microsoft on 2/14/2008 at 11:02 PM
Thanks for your feedback. We are escalating this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you,
Visual Studio Product Team