Event Fires twice for dynamic RadioButtonList

M

Mike Salter

I created a page that reads a DB for questions and possible answers
(usuallyYes/No). I create a panel for each group of questions, and add a
panel for each question to the Group panel. To the Question panel I add a
label with the question text, and a radiobuttonlist with the answers. I
have an eventhandler I add to each radiobuttonlist, which is the same for
all.

The Group panels are then added to Placeholder1.Controls. I then add each
panel to an arraylist arlPanels and do a "Session["arlPanels"] = arlPanels;"
when all are created. This is done in CreatePanesl(). In PersistPanels(),
I get the arlPanels from Session, and add them to Placeholder1.Controls.
This all works pretty good so far. When I click an answer to question 1,
the event fires, no problem. However, when I then click an answer to
question 2, the event fires for question 1 again, and then question 2. The
only way I can seem to prevent this is to set the radiobuttonlist Enabled =
false; in the eventhandler..

I am kinda new to dynamically creating controls in ASP.NET, but I have read
that there are glitches. I would appreciate any suggestions.

In Page_Load:
IF (!IsPostBack)
{
CreatePanels();
}
else
{
PersistPanels();
}
 
S

samuelrobertson

This is normal. You are changing both radio button list values (and
you are using SelectedIndexChanged), so when you do a postback both
events are fired. Probably if you leave question 1 alone that won't
fire.

I'd use the radiobuttonlist(s).SelectedValue(s) instead in the submit
button click postback hander instead to determine what the values are.

BTW, why are you using Session? Why not just:
In Page_Load:
CreatePanels();
 
M

Mike Salter

Actually, when I click an answer to question #1, it immediately posts back.
I need to do this as the visibility of subsequent questions depends on
previous answers. Then when I click an answer to question #2, the
eventhandler fires for question #1 again, AND then for question #2
immediately after that. Weird!

I use Session, as there are a lot of questions/answers, and I create then
from classes loaded from a DB at Application Start. Retrieving the panels
from Session is quicker:

private void PersistPanels()
{
PlaceHolder1.Controls.Clear();
arlPanels = Session["arlPanels"] as ArrayList;
if (arlPanels!=null)
{
Panel pnl;
for (int i = 0;i < arlPanels.Count;i++)
{
pnl = (Panel) arlPanels;
PlaceHolder1.Controls.Add(pnl);
}
}
}
 
S

samuelrobertson

It isn't weird. Both radio button lists are have changed values from
the time they were built. When you click one you cause the whole
pageto be rebuilt, and that's why the change value event fires for
both. Thats why I think if you put the question 1 answer back to its
default value and then click question 2 you will only get the question
2 event. You might try this just for experimentation.

I forgot that you have AutoPostBack set to true for these controls so
when you click them a postback happens automatically. I understand
that you just want the new question event to fire. How to solve?
Hmmmmm... Can you use different event handlers? You could also detect
the GroupName property of the individual items in the RadioButtonList
to see which question has been clicked. I know you must be giving them
unique values on the form or they wouldn't function as grouped radio
buttons. So your event handler would look like
if(radioButton.item[0].GroupName == "question1") {... do stuff }

Anyway, if anyone else has ideas?
 
M

Mike Salter

My current solution is shown below. I setup a Hashtable which stores the ID
of the radiobutton list (which contains the Group# and Question #) and the
SelectedValue. When the event fire for a radiobutton list, it checks to see
if that ID/Value combo exists in the Hashtable. If the exact ID/Value
combination exists, it returns from the event handler. Otherwise it
adds/replaces the ID/Value.

The one thing noticed is that the radiobuttonlists retain their values
between postbacks, which is what I want. I do not want then to revert back
to their original values. I do, however want the user to be able to go back
and change them, which is going to make the conditional display of
subsequent questions interesting. (If you go back and kill your
grandfather, you no longer exist!) This is a user requirement, so that is
what I need to do.

Anyway, thanks for your help. Any more creative solutions would be
appreciated.
//----------------------------------------------------------------
// Generic Event for Question RadioButtonList
//----------------------------------------------------------------
private void rblQuestion_SelectedIndexChanged(object sender,
System.EventArgs e)
{
htQuestionAnswer = Session["htQuestionAnswer"] as Hashtable;
RadioButtonList rbl;
rbl = (RadioButtonList) sender;

if (htQuestionAnswer.ContainsKey(rbl.ID))
{
if (htQuestionAnswer[rbl.ID].ToString() == rbl.SelectedValue)
{
// Ignore dup event
return;
}
else
{
// replace value, save Hashtable
htQuestionAnswer[rbl.ID] = rbl.SelectedValue;
Session["htQuestionAnswer"] = htQuestionAnswer;
}
}
else
{
// add value, save Hashtable
htQuestionAnswer.Add(rbl.ID,rbl.SelectedValue);
Session["htQuestionAnswer"] = htQuestionAnswer;
}

// Logic goes here
}

It isn't weird. Both radio button lists are have changed values from
the time they were built. When you click one you cause the whole
pageto be rebuilt, and that's why the change value event fires for
both. Thats why I think if you put the question 1 answer back to its
default value and then click question 2 you will only get the question
2 event. You might try this just for experimentation.

I forgot that you have AutoPostBack set to true for these controls so
when you click them a postback happens automatically. I understand
that you just want the new question event to fire. How to solve?
Hmmmmm... Can you use different event handlers? You could also detect
the GroupName property of the individual items in the RadioButtonList
to see which question has been clicked. I know you must be giving them
unique values on the form or they wouldn't function as grouped radio
buttons. So your event handler would look like
if(radioButton.item[0].GroupName == "question1") {... do stuff }

Anyway, if anyone else has ideas?
 
S

sam

It looks good. Although you could probably replace it with this:

private void rblQuestion_SelectedIndexChang­ed(object sender,
System.EventArgs e)
{
htQuestionAnswer = Session["htQuestionAnswer"] as Hashtable;
RadioButtonList rbl;
rbl = (RadioButtonList) sender;
htQuestionAnswer[rbl.ID] = rb­l.SelectedValue;
Session["htQuestionAnswer"] = htQuestionAnswer;

// Logic goes here
}

cause I think hashtables will automatically add the key if it doesn't
exist and the rest of your code is just optimization.

Anyway, I may try to think of something else. Technically, I *am* at
work so work asp.net has to come first ;).

-Sam
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top