Accessing Controls on ListView Edit Command
Asked Answered
N

2

0

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
Nailhead answered 24/1, 2012 at 21:6 Comment(3)
Have you looked here #825548. Which event are you trying to access the control in?Jewel
@PaulMcCowat Yes, and I'm looking at it more closely now, but I'm still having trouble connecting the dots. How do I "tell" the ItemDataBound DropDownList that the SelectedValue should the one from the ItemCommand event? i.e. How do I pass that data between event? Or am I thinking about it wrong? See how confused I am? :'(Nailhead
It looks like you are finding the NewProductName_ddl as if it's one instance. That's probably going to return a collection of DropDownLists. It's really hard to help you and write the code without having the full html and code behind available.Degradation
N
2

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. :)

Nailhead answered 25/1, 2012 at 17:49 Comment(0)
F
2

Great post! I had the same problem and you saved me hours of trial and error. Just wanted to point out that when using your first option with .NET Framework 3.5 or lower, DataItemIndex isn't available. To work around it you can replace

If i = e.Item.DataItemIndex Then

With

If i = DirectCast(e.Item, IDataItemContainer).DataItemIndex Then
Fulford answered 24/4, 2012 at 11:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.