Link to home
Start Free TrialLog in
Avatar of tmccrank
tmccrank

asked on

Distribution of items from an ArrayList to a particular instance of a Repeater

Hi,

I'm trying to populate a RadioButtonList (each RadioButton is a possible multiple-choice answer) that is within a Repeater (each being a question).  The RBL is being populated by an ArrayList.  The format should look something like this:

Repeater1 (i.e. Question 1)
  RB1  (i.e. multiple-choice 1)
  RB2  (m-c 2)  etc...
  RB3
  RB4
  RB5

Repeater2
  RB1
  RB2
  RB3
  RB4
  RB5

Right now, I have all the answers for ALL the questions showing up under EACH question:

Repeater1
   RB1
   RB2
   RB3
   RB4
   RB5
   RB1
   RB2
   RB3
   RB4
   RB5

Repeater2
   RB1
   RB2
   RB3
   RB4
   RB5
   RB1
   RB2
   RB3
   RB4
   RB5

How can I take specific strings from the ArrayList and populate specific instances of a repeater with them?  Here's what my ItemDataBound code for the Repeater looks like:

    Public Sub rptQuestions_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptQuestions.ItemDataBound
        Dim lt As ListItemType = e.Item.ItemType
        If lt = ListItemType.Item OrElse lt = ListItemType.AlternatingItem Then
            Dim strAnswers As String = CType(e.Item.DataItem, String)
            If Not strAnswers Is Nothing Then
                Dim rblAnswers As RadioButtonList = CType(e.Item.FindControl("rblAnswers"), RadioButtonList)
                If Not rblAnswers Is Nothing Then
                    Dim alAnswers As ArrayList
                    alAnswers = DA.PopulateAnswers(CInt(Request.QueryString(0)))
                    rblAnswers.DataSource = alAnswers
                    rblAnswers.DataBind()
                End If
            End If
        End If
    End Sub

Hope this isn't too confusing.
Jens
Avatar of sachitjain
sachitjain
Flag of India image

I think checkboxlist control is the better option if u want to have multiple choice answers.

Scenario should be like, take a repeater control with a label and checkboxlist (label to display question, checkboxlist to display answers) and bind that repeater with the datasource(table populated with questions and possible options for those questions).

I don't think u need to have a separate repeater control for each question.

If my understanding is not clear about ur question then plz correct me.

Regards
Sachit.
Avatar of tmccrank
tmccrank

ASKER

Hi Sachit,

The .aspx page code looks like this:

--------------------------------

      <body MS_POSITIONING="GridLayout">
            <form id="Form1" method="post" runat="server">
                  <asp:repeater id="rptQuestions" runat="server" OnItemDataBound="rptQuestions_ItemDataBound">
                        <HeaderTemplate>
                              <ol>
                        </HeaderTemplate>
                        <ItemTemplate>
                              <li>
                                    <%# Container.DataItem %>
                              </li>
                              <asp:RadioButtonList ID="rblAnswers" Runat="server"></asp:RadioButtonList>
                        </ItemTemplate>
                        <FooterTemplate>
                              </ol>
                        </FooterTemplate>
                  </asp:repeater>
            </form>
      </body>

--------------------------------

As you can see, I have a RadioButtonList nested in a Repeater control.  Each control gets its data from separate tables: one table for the questions (the repeater), and one for the list of possible answers (the RBL).  A DataReader is used to read the data into separate ArrayLists which then are the data sources for each control.  I want the RBL control (not the CheckBoxList) since the user should be able to choose only one of five answers for each question.

So, my main question is, how do I populate each question with the list of answers that are relevant to only that question?

Here's the Page_Load event code:

--------------------------------

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'retrieve ArrayList
        Dim alQuestions As ArrayList
        alQuestions = DA.PopulateQuestions(CInt(Request.QueryString(0)))

        'bind the questions repeater to the alQuestions ArrayList
        rptQuestions.DataSource = alQuestions
        rptQuestions.DataBind()

    End Sub

--------------------------------

And here is the ItemDataBound code for populating the RadioButtonList:

--------------------------------

    Public Sub rptQuestions_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptQuestions.ItemDataBound
        Dim lt As ListItemType = e.Item.ItemType
        If lt = ListItemType.Item OrElse lt = ListItemType.AlternatingItem Then
            Dim strAnswers As String = CType(e.Item.DataItem, String)
            If Not strAnswers Is Nothing Then
                Dim rblAnswers As RadioButtonList = CType(e.Item.FindControl("rblAnswers"), RadioButtonList)
                If Not rblAnswers Is Nothing Then
                    Dim alAnswers As ArrayList
                    alAnswers = DA.PopulateAnswers(CInt(Request.QueryString(0)))
                    rblAnswers.DataSource = alAnswers
                    rblAnswers.DataBind()
                End If
            End If
        End If
    End Sub

--------------------------------

Thanks
Jens
Maybe this would be easier if I pulled down the data from the two SQL tables into one ArrayList instead of two.

If I do that I need to figure out how to populate the Questions Repeater AND the Answer RBL (nested in the Repeater) from the ArrayList...
What i m noticing here is that u r creating separate arraylists for binding questions.
In ItemDataBound, plz verify that DA.PopulateAnswers method is returning answers for respective question because ItemDataBound event would execute once for each question.
Say one question is there with quesitionNo as 1 and 1A, 1B, 1C, 1D and 1E are possible options for question 1 then when ItemDataBound is getting executed for question 1, ur method DA.PopulateAnswers should set the arraylist with records 1A to 1E only.

Regards
Sachit.
Sachit,
Yes, DA.PopulateAnswers is returning an ArrayList of answers for each question.  Here's the code:

----------------------------

    Public Function PopulateAnswers(ByVal QuestID As Integer) As ArrayList

        Dim alPopAnswers As New ArrayList
        Dim strPopAnswers As String = ("SELECT a.Answers, a.QuestionsID, q.QuestionsID, q.ModuleID, m.ModuleID ")
        strPopAnswers = strPopAnswers & ("FROM Answers a INNER JOIN Questions q ")
        strPopAnswers = strPopAnswers & ("ON a.QuestionsID = q.QuestionsID ")
        strPopAnswers = strPopAnswers & ("INNER JOIN Modules m ON q.ModuleID = m.ModuleID WHERE m.ModuleID='") & QuestID + 1 & ("'")
        Dim drPopAnswers As SqlDataReader
        Dim commPopAnswers As New SqlCommand(strPopAnswers, conNEM)

        Try
            'open connection
            conNEM.Open()

            'execute reader, then close connection
            drPopAnswers = commPopAnswers.ExecuteReader(CommandBehavior.CloseConnection)

            'iterate through result set, add to ArrayList
            While drPopAnswers.Read()
                alPopAnswers.Add(drPopAnswers("Answers"))
            End While

        Catch ex As Exception
            ex.ToString()

        Finally
            'close datareader
            drPopAnswers.Close()

        End Try

        Return alPopAnswers

    End Function

-----------------------------------

To use your analogy, if I have 3 Questions, what I'm ending up with is:

Question 1: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E
Question 2: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E
Question 3: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E

So the answers for all 3 questions are showing up for each question.  Of course it should be like this:

Question 1: 1A, 1B, 1C, 1D, 1E
Question 2: 2A, 2B, 2C, 2D, 2E
Question 3: 3A, 3B, 3C, 3D, 3E

Get it?  Do you think it would be better if I have just one ArrayList (with the questions and answers from the SQL DB tables) and somehow iterate through it to populate the Questions Repeater and the Answers RadioButtonList?  If so, how could that be done?

If I stay with two ArrayLists, I somehow need to loop through the Answers ArrayList where the loop recognizes which Question index it's on.  The problem here is that the Questions are in another ArrayList.  That's why I'm thinking it might be better to have one ArrayList instead of two.

Thanks and regards,
Jens
ASKER CERTIFIED SOLUTION
Avatar of sachitjain
sachitjain
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sachit,
Thanks for your help.  I looks like using a DataTable is the way to go, I was hoping to stay with using ArrayLists since they're such light-weight objects compared to DataSets.  There seems to be a growing number of people out there who are actively advising against using DataSets under ANY circumstances!

I'm not sure yet how to use the RowFilter property, but that's another problem that I'll try to figure out.

Jens