Click to See Complete Forum and Search --> : Help! Custom Control ... event from child control not firing...?


THY02K
May 12th, 2005, 06:01 AM
Problem: Help! Custom Control ... event from child control not firing...?

I am building this custom control, which consists of the following child controls:
1. a textbox (txtSelectedOptionText)
2. a button (btnToggle)
3. a listbox (multi-select) (lstOptions)
4. a bunch of other controls (but not relevant to our discussion)

Basically, the button toggles visibility of the listbox via javascript. And the textbox display values selected in listbox in "comma-delimited" format. However, the problem is, I want to persist listbox selection in ViewState. I tried to do this by adding a handler to respond to onclick event for btnToggle (trying to retrieve selected options there, and put it in "ViewState"). For some reason the event handler is NEVER fired?!!? Any idea? When I had the debugger on... I can see: CreateChildControls() and Render() got fired but... none of my event handlers...???

Thanks in advance!

************************************************************
Here's the code:

Imports System.IO
Imports System.ComponentModel

Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace application.ui.controls.webcontrols

<{0}:MultiSelectDropDown runat=server />")> Public Class MultiSelectDropDown
Inherits System.Web.UI.WebControls.WebControl

Protected txtSelectedOptionText As TextBox = New TextBox
Protected WithEvents btnToggle As ImageButton = New ImageButton
Protected lstOptions As ListBox = New ListBox
' other stuff...

Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
'bunch of rendering...
Return
End Sub

Protected Overrides Sub CreateChildControls()
...
Controls.Add(txtSelectedOptionText)
Controls.Add(btnToggle)
...
Controls.Add(lstOptions)
...

MyBase.CreateChildControls()
End Sub

Protected Sub OnToggle(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnToggle.Click
'*** My intention is to retrieve option selected in lstOptions here and put it in ViewState... But this event handler is never fired???
Return
End Sub
End Class

End Namespace

cmiskow
May 12th, 2005, 10:52 AM
Custom controls are supposed to implement the INamingContainer interface to ensure that the child controls get proper unique ids and what not. The interface has no members, its just there to tell ASP.NET to handle the control properly. This might be the source of your problem.

Also, webcontrols (like ListBox) should automatically handle their own ViewState as long as they are added in the CreateChildControls method. Implementing INamingContainer might fix this as well.

THY02K
May 12th, 2005, 11:41 AM
Custom controls are supposed to implement the INamingContainer interface to ensure that the child controls get proper unique ids and what not. The interface has no members, its just there to tell ASP.NET to handle the control properly. This might be the source of your problem.

Also, webcontrols (like ListBox) should automatically handle their own ViewState as long as they are added in the CreateChildControls method. Implementing INamingContainer might fix this as well.

Thanks, first of all. I will try implement INamingContainer first. But, not sure what you mean exactly "... added in "CreateChildControls"? ..."

cmiskow
May 12th, 2005, 12:44 PM
Sorry to confuse you. I just meant that as long as the web controls are added to your custom control's controls collection inside the CreateChildControls method, their ViewState should be handled automatically. You do this already, here:


Protected Overrides Sub CreateChildControls()
...
Controls.Add(txtSelectedOptionText)
Controls.Add(btnToggle)
...
Controls.Add(lstOptions)


so you have nothing to worry about.

One other thing I should mention, is that you are supposed to call EnsureChildControls() before accessing any of the child controls, to ensure that the controls are already initialized. The simplest way I've seen to do this is to override the controls collection, like so:


Public Overrides ReadOnly Property Controls As ControlCollection
Get
EnsureChildControls()
Return MyBase.Controls
End Get
End Property


That way, EnsureChildControls() is automatically called every time you try to access the controls collection.

THY02K
May 12th, 2005, 11:28 PM
I did two things, and the events (or handler) for my IMAGE BUTTON is still not fired (BUT ***, for my ListBox with AutoPostBack set to true, event handler was fired):

1. Implement INamingContainer
2. Added this:

Public Overrides ReadOnly Property Controls() As ControlCollection
Get
EnsureChildControls()
Return MyBase.Controls
End Get
End Property

... Any idea?

Norman Fung

THY02K
May 13th, 2005, 12:15 AM
Anyway, after I got my events working for my listbox (to respond to selection changed event), I'm still having trouble trying to retrieve selected option on server side:

Protected Sub OnListSelectionChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim options As Hashtable = New Hashtable
Dim lstBx As ListBox

lstBx = CType(sender, ListBox)
For Each item As ListItem In lstBx.Items
If item.Selected Then
'THIS LINE NEVER GETS EXECUTED?!? (Probably my list box has been reinitialized or destroyed... before the event handler is ever called...)
options.Add(item.Value, item.Text)
End If
Next item

'This really is what I tried to do.
ViewState("SelectedOptions") = options

Return
End Sub

'I want to expose selected options to server side processing:
Public ReadOnly Property SelectedOptions As Hashtable
Get
Return ViewState("SelectedOption")
End Get
End Property

Any pointer? I'm not familiar with event bubbling mechanism, but, must I investigate the subject fully before I can get this working?? I need to get this done fast... Thanks!

Norman Fung

cmiskow
May 13th, 2005, 09:32 AM
For the image button event handler, try adding this in CreateChildControls():


AddHandler btnToggle, AddressOf OnToggle


I'll try to look at the other part a little later

THY02K
May 14th, 2005, 10:47 PM
Thanks for feedback first of all.

...For the image button event handler, try adding this in CreateChildControls()... AddHandler...

I did, in fact, I tried:
1. AddHandler
2. Protected Sub OnToggle_Clicked(sender As Object, e As ...EventArgs) Handles btnToggle.Clicked

...
End

Perhaps it has to do with sequence in which ... controls are added.

...
Controls.Add(lstOptions)
Controls.Add(btnToggle)
...

I don't know, don't have much clue.

My biggest problem now is not this however. It's with how to retrieve "selected" options from lstOptions.... My event handler for my select list lstOptions gets fired everytime selection changes (although preferred to handle when btnToggle is clicked), when I loop through select list's options, all selection is lost?? I think selection is lost on postbacks when the entire control (composite control with textbox+listbox as child control) is re-created (ie. New). Btw, enabling ViewState on listbox didn't help.



Help!

THY02K
May 14th, 2005, 11:09 PM
I just read MSDN article on "Bubbling an Event"... doesn't look like my problem (retrieving list selection on postbacks) has any concerns in regards to event bubbling. Any pointer anyone?

coolbiz
May 16th, 2005, 07:31 AM
It is going to be hard to help troubleshooting this coz the error might come from somewhere else. The easiest way is to post a sample app that has and uses your custom control.