Wednesday, April 13, 2011

Finding controls in nested listviews

I'm building a collapsible grouping grid using Matt Berseth's example from mattberseth.com/blog/2008/01/building_a_grouping_grid_with.html

It has an inner listview "lvInner" nested in an outer listview "lvOuter". I'm trying to access a textbox in lv_Inner using

Protected Sub lvInner_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles lvInner.ItemDataBound

    If e.Item.ItemType = ListViewItemType.DataItem Then

     Dim tb As TextBox = TryCast(e.Item.FindControl("lvOuter").FindControl("lvInner").FindControl("TextBox1"), TextBox)
           ' Do something to TextBox1

     End If
EndSub

I get an "Object reference not set to an instance of an object" error on line Dim tb.

From stackoverflow
  • You need to simply do e.Item.FindControl("textbox"), e.Item is already scoped to the the proper listView.

    Protected Sub lvInner_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles lvInner.ItemDataBound
    
    If e.Item.ItemType = ListViewItemType.DataItem Then
    
     Dim tb As TextBox = TryCast(e.Item.FindControl("TextBox1"), TextBox)
           ' Do something to TextBox1
    
     End If
    EndSub
    
  • FindControl is handy, but not recursive.

    If you have deep nesting of controls on a page, you might need to recursively search through the control hierarchy of the page to find the control you need.

    write your own method...

    C# example: (Convert using any free VBtoC# online tool)

    public static System.Web.UI.Control FindControlFromTop(System.Web.UI.Control start, string id, System.Web.UI.Control exclude)
         {
          System.Web.UI.Control foundControl;
    
          if (start != null && id != null)
          {
           foundControl = start.FindControl(id);
    
           if (foundControl != null)
            if(foundControl.ID.Equals(id))
             return foundControl;
    
           foreach (System.Web.UI.Control control in start.Controls)
           {
            if (control != exclude)
             foundControl = FindControlFromTop(control, id, null);
    
            if (foundControl != null)
             if (foundControl.ID.Equals(id))
              return foundControl;
           }
          }
    
          return null;
         }
    
    FlySwat : Two things... He doesn't need recursion as e.Item is already on the inner list (look at his code)...and two, you can make your recursive method about 10 lines shorter.

0 comments:

Post a Comment