Search code examples
asp.netvb.netlistviewinitializationfindcontrol

Accessing Controls on ListView Edit Command


In my ListView I have an ItemTemplate and EditItemTemplate which look something like this, respectively.

enter image description here -------> enter image description here

When I click the "Edit" button, and it switches to the EditItemTemplate view on the right, I want to prefill the Textbox and select the corresponding option in the DropDownList. How can I do this?

Before you say to use something like the following, please know that I've already explored every possible variation I can think of. Sorry to be so demanding, but please be prepared to walk me through this one if you answer. ^.^ I've been stuck on this issue for literally months :(

Dim lv As ListView = DirectCast(sender, ListView) 'sender is the ListView on the ItemCommand event
Dim ddl As DropDownList = DirectCast(lv.Items(0).FindControl("NewProductName_ddl"), DropDownList)
Dim tb As TextBox = DirectCast(lv.Items(0).FindControl("NewProductName_tb"), TextBox)

UPDATE - RAWR!!

Oh my freaking goodness, SO CLOSE, but no cigar. The following code worked for prefilling when only one item was in the ListView, but when more than one items exist, it throws a NullReferenceException :(

'PROBLEM WAS HERE: Compare to the working code in my answer.
Protected Sub NewProduct_ItemDataBound(ByVal sender As ListView, ByVal e As ListViewItemEventArgs) Handles NewProduct.ItemDataBound
    If sender.EditIndex > -1 Then
        Dim ddl As DropDownList = DirectCast(e.Item.FindControl("NewProductName_ddl"), DropDownList)
        Dim tb As TextBox = DirectCast(e.Item.FindControl("NewProductName_cb"), TextBox)

        ddl.Items.FindByValue(sender.DataKeys(sender.EditIndex)("ID").ToString).Selected = True 'Prefills the DropDownList
        tb.Text = sender.DataKeys(sender.EditIndex)("Product").ToString 'Prefills the TextBox
    End If
End Sub

Solution

  • EUREKA!!

    I am elated beyond imagination!! All caps, nor bold do justice to how happy I am right now :)

    First I wanna give props to this question which got me pointed in the right direction. Now onto the answer, which is the most ideal variation I have found of the answer provided in the above link:

    The ItemDataBound event is the key, but it's important to note that this event will fire for each item that exists in your ListView and for that reason, you must be careful in your approach. Here are two options that worked equally well for me.

    Option 1 - Most elegant; only runs FindControl on the item in question rather than all items.

    Protected Sub NewProduct_ItemDataBound(ByVal sender As ListView, ByVal e As ListViewItemEventArgs) Handles NewProduct.ItemDataBound
        Dim i As Integer = sender.EditIndex
        If i = e.Item.DataItemIndex Then
            Dim ddl As DropDownList = DirectCast(e.Item.FindControl("NewProductName_ddl"), DropDownList)
            Dim tb As TextBox = DirectCast(e.Item.FindControl("NewProductName_cb"), TextBox)
    
            ddl.Items.FindByValue(sender.DataKeys(i)("ID").ToString).Selected = True 'Prefills the DropDownList
            tb.Text = sender.DataKeys(i)("Product").ToString 'Prefills the TextBox
        End If
    End Sub
    

    Option 2 - Based on the referenced question, but with a crucial check to ensure non-null object.

    Protected Sub NewProduct_ItemDataBound(ByVal sender As ListView, ByVal e As ListViewItemEventArgs) Handles NewProduct.ItemDataBound
        Dim i As Integer = sender.EditIndex
        If i > -1 Then
            Dim ddl As DropDownList = DirectCast(e.Item.FindControl("NewProductName_ddl"), DropDownList)
            Dim tb As TextBox = DirectCast(e.Item.FindControl("NewProductName_cb"), TextBox)
    
            If Not IsNothing(ddl) Then
                ddl.Items.FindByValue(sender.DataKeys(i)("ID").ToString).Selected = True 'Prefills the DropDownList
            End If
            If Not IsNothing(tb) Then
                tb.Text = sender.DataKeys(i)("Product").ToString 'Prefills the TextBox
            End If
        End If
    End Sub
    

    I may make improvements to this answer later, but this did the trick for me. :)