帮助! 获取动态控制单选按钮的值!

发布于 2024-07-27 03:07:26 字数 6932 浏览 8 评论 0原文

我正在考虑创建一个动态调查,如从动态控件获取用户输入中发布的那样,但环境有所不同。

以下是我想要做的:

首先,当用户单击按钮时,它将在占位符内填充一个带有单选按钮的动态表格,用于调查问卷。 但是,单击提交按钮后我无法获取其值(用于分数计算)。 所有的动态控制都消失了。 除此之外,我正在使用 ajax 扩展(updatePanel)进行开发和 我已经研究过 viewstate 但我不知道它。

有人有什么想法吗?

这里我包含了一些代码:


页面

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:Button ID="btnTest" runat="server" Text="Take Test" OnClick="btnTest_Click" Visible="False" />
            <asp:Label ID="lblTestErrMsg" runat="server" 

ForeColor="Red"></asp:Label><br />
                <table id="tblTest" runat="server" style="width: 100%">
                    <tr>
                        <td>
                         <asp:PlaceHolder ID="phQuestionnaire" runat="server"></asp:PlaceHolder>
                            <br />
                            </td>
                    </tr>
                    <tr>
                        <td>
                            </td>
                    </tr>
                    <tr>
                        <td>
                            <asp:Label ID="lblResult" runat="server"></asp:Label></td>
                    </tr>
                    <tr>
                        <td>
                        </td>
                    </tr>
                </table>
            </ContentTemplate>
        </asp:UpdatePanel>

创建动态表函数

*v_dtTable 和 v_dtTable2 包含数据库中的数据

     Private Sub CreateDynamicTable(ByVal v_dtTable As Data.DataTable, ByVal v_dtTable2 As Data.DataTable)
    Me.phQuestionnaire.Controls.Clear()
    Dim cols As Integer = v_dtTable.Rows.Count + 2
    Dim rows As Integer = v_dtTable2.Rows.Count + 1
    Dim mid As Integer = v_dtTable.Rows.Count / 2

    Dim tbl As Table = New Table()
    tbl.ID = "tblQs"
    tbl.BorderWidth = 1
    tbl.CellPadding = 0
    tbl.CellSpacing = 0
    tbl.Width = 500
    tbl.EnableViewState = True

    Me.phQuestionnaire.Controls.Add(tbl)
    For i As Integer = 0 To rows - 1
        Dim tr As TableRow = New TableRow()
        Dim rowCnt As Integer = 1
        Dim colCnt As Integer = 0

        For j As Integer = 0 To cols - 1
            Dim tc As TableCell = New TableCell()
            tc.BorderWidth = 1
            Dim lbl As Label = New Label()
            Dim bol As Boolean = False

            If i = 0 Then       
                If j = 0 Then
                    tc.Text = "No."

                ElseIf j = 1 Then
                    tc.Text = "Question"

                Else
                    tc.Text = v_dtTable.Rows(j - 2).Item("scoreName")
                    tc.HorizontalAlign = HorizontalAlign.Center
                End If
                tc.BackColor = Drawing.Color.DeepSkyBlue
                tc.ForeColor = Drawing.Color.White
            Else
                If v_dtTable2.Rows(i - 1).Item("isHeader") Then
                    bol = True
                    tc.Text = v_dtTable2.Rows(i - 1).Item("TestQuestion")
                    tc.Style("font-weight") = "bold"

                ElseIf j = 0 Then
                    tc.Text = rowCnt
                    rowCnt += 1

                ElseIf j = 1 Then
                    tc.Text = v_dtTable2.Rows(i - 1).Item("TestQuestion")

                Else
                    Dim rBtn As RadioButton = New RadioButton
                    rBtn.GroupName = "rBtn" & rowCnt
                    rBtn.ID = "rBtn_" & rowCnt & "_" & colCnt
                    rBtn.InputAttributes("value") = v_dtTable.Rows(j - 2).Item("scoreValue")
                    colCnt += 1
                    If j = mid + 2 Then
                        rBtn.Checked = True
                    End If

                    tc.Controls.Add(rBtn)
                    tc.HorizontalAlign = HorizontalAlign.Center
                End If
            End If

            If bol Then
                tc.ColumnSpan = cols - 1
                tr.Cells.Add(tc)
                Exit For
            Else
                tr.Cells.Add(tc)
            End If
        Next j

        tbl.Rows.Add(tr)                          
    Next i
End Sub

计算分数函数

    Private Sub subCalculateScore()
    Dim tblQs As Table = CType(Me.phQuestionnaire.FindControl("tblQs"), Table)
    Dim rb As New RadioButton
    Dim score As Integer = 0

    If Me.phQuestionnaire.FindControl("tblQs") Is Nothing Then
    Else
        For Each tr As TableRow In tblQs.Rows
            For Each tc As TableCell In tr.Cells
                For Each c As Control In tc.Controls
                    If c.GetType.ToString = rb.GetType.ToString Then
                        Dim rBtn As RadioButton = CType(c, RadioButton)
                        If rBtn.Checked Then
                            Dim strScore As String = rBtn.InputAttributes("value")
                            score += CInt(strScore)
                        End If
                    End If
                Next
            Next
        Next
    End If

    Me.Label1.Text = score
End Sub

查看动态生成表的源代码

  <table id="tblQs" cellspacing="0" cellpadding="0" border="0" style="border-width:1px;border-style:solid;width:500px;border-collapse:collapse;"><tr>           
<td style="border-width:1px;border-style:solid;"><span>No.</span></td>
<td style="border-width:1px;border-style:solid;"><span>Question</span></td>
<td style="border-width:1px;border-style:solid;"><span>dislike</span></td>
<td style="border-width:1px;border-style:solid;"><span>normal</span></td>
<td style="border-width:1px;border-style:solid;"><span>like</span></td>
<td style="border-width:1px;border-style:solid;"><span>vry likes</span></td></tr><tr>
<td style="border-width:1px;border-style:solid;"><span>1</span></td>
<td style="border-width:1px;border-style:solid;"><span>question 1</span></td>
<td style="border-width:1px;border-style:solid;">
    <input id="rBtn_1_0" type="radio" name="rBtn1" value="rBtn_1_0" value="0" /></td>
<td style="border-width:1px;border-style:solid;">
    <input id="rBtn_1_1" type="radio" name="rBtn1" value="rBtn_1_1" value="1" /></td>
<td style="border-width:1px;border-style:solid;">
    <input id="rBtn_1_2" type="radio" name="rBtn1" value="rBtn_1_2" checked="checked" value="2" /></td>
<td style="border-width:1px;border-style:solid;">
    <input id="rBtn_1_3" type="radio" name="rBtn1" value="rBtn_1_3" value="3" /></td></tr></table>

I am looking into create a dynamic survey as posted in Get User Input From Dynamic Controls but with some different environment.

Below is what i am trying to do:

First when the user click the button, it will populate a dynamic table with radio button for the survey questionnaire inside a placeholder. However, I was unable to get its value (for score calculation) after clicking the submit button.
All the dynamic controls was gone.
Beside i am using an ajax extension (updatePanel) for the development and
I have been look into viewstate but I have no idea with it.

Does anyone have any ideas?

Here i included some of my code:


Page

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:Button ID="btnTest" runat="server" Text="Take Test" OnClick="btnTest_Click" Visible="False" />
            <asp:Label ID="lblTestErrMsg" runat="server" 

ForeColor="Red"></asp:Label><br />
                <table id="tblTest" runat="server" style="width: 100%">
                    <tr>
                        <td>
                         <asp:PlaceHolder ID="phQuestionnaire" runat="server"></asp:PlaceHolder>
                            <br />
                            </td>
                    </tr>
                    <tr>
                        <td>
                            </td>
                    </tr>
                    <tr>
                        <td>
                            <asp:Label ID="lblResult" runat="server"></asp:Label></td>
                    </tr>
                    <tr>
                        <td>
                        </td>
                    </tr>
                </table>
            </ContentTemplate>
        </asp:UpdatePanel>

Create Dynamic Table function

*v_dtTable and v_dtTable2 contains the data from database

     Private Sub CreateDynamicTable(ByVal v_dtTable As Data.DataTable, ByVal v_dtTable2 As Data.DataTable)
    Me.phQuestionnaire.Controls.Clear()
    Dim cols As Integer = v_dtTable.Rows.Count + 2
    Dim rows As Integer = v_dtTable2.Rows.Count + 1
    Dim mid As Integer = v_dtTable.Rows.Count / 2

    Dim tbl As Table = New Table()
    tbl.ID = "tblQs"
    tbl.BorderWidth = 1
    tbl.CellPadding = 0
    tbl.CellSpacing = 0
    tbl.Width = 500
    tbl.EnableViewState = True

    Me.phQuestionnaire.Controls.Add(tbl)
    For i As Integer = 0 To rows - 1
        Dim tr As TableRow = New TableRow()
        Dim rowCnt As Integer = 1
        Dim colCnt As Integer = 0

        For j As Integer = 0 To cols - 1
            Dim tc As TableCell = New TableCell()
            tc.BorderWidth = 1
            Dim lbl As Label = New Label()
            Dim bol As Boolean = False

            If i = 0 Then       
                If j = 0 Then
                    tc.Text = "No."

                ElseIf j = 1 Then
                    tc.Text = "Question"

                Else
                    tc.Text = v_dtTable.Rows(j - 2).Item("scoreName")
                    tc.HorizontalAlign = HorizontalAlign.Center
                End If
                tc.BackColor = Drawing.Color.DeepSkyBlue
                tc.ForeColor = Drawing.Color.White
            Else
                If v_dtTable2.Rows(i - 1).Item("isHeader") Then
                    bol = True
                    tc.Text = v_dtTable2.Rows(i - 1).Item("TestQuestion")
                    tc.Style("font-weight") = "bold"

                ElseIf j = 0 Then
                    tc.Text = rowCnt
                    rowCnt += 1

                ElseIf j = 1 Then
                    tc.Text = v_dtTable2.Rows(i - 1).Item("TestQuestion")

                Else
                    Dim rBtn As RadioButton = New RadioButton
                    rBtn.GroupName = "rBtn" & rowCnt
                    rBtn.ID = "rBtn_" & rowCnt & "_" & colCnt
                    rBtn.InputAttributes("value") = v_dtTable.Rows(j - 2).Item("scoreValue")
                    colCnt += 1
                    If j = mid + 2 Then
                        rBtn.Checked = True
                    End If

                    tc.Controls.Add(rBtn)
                    tc.HorizontalAlign = HorizontalAlign.Center
                End If
            End If

            If bol Then
                tc.ColumnSpan = cols - 1
                tr.Cells.Add(tc)
                Exit For
            Else
                tr.Cells.Add(tc)
            End If
        Next j

        tbl.Rows.Add(tr)                          
    Next i
End Sub

Calculate Score function

    Private Sub subCalculateScore()
    Dim tblQs As Table = CType(Me.phQuestionnaire.FindControl("tblQs"), Table)
    Dim rb As New RadioButton
    Dim score As Integer = 0

    If Me.phQuestionnaire.FindControl("tblQs") Is Nothing Then
    Else
        For Each tr As TableRow In tblQs.Rows
            For Each tc As TableCell In tr.Cells
                For Each c As Control In tc.Controls
                    If c.GetType.ToString = rb.GetType.ToString Then
                        Dim rBtn As RadioButton = CType(c, RadioButton)
                        If rBtn.Checked Then
                            Dim strScore As String = rBtn.InputAttributes("value")
                            score += CInt(strScore)
                        End If
                    End If
                Next
            Next
        Next
    End If

    Me.Label1.Text = score
End Sub

View source for the dynamic generated table

  <table id="tblQs" cellspacing="0" cellpadding="0" border="0" style="border-width:1px;border-style:solid;width:500px;border-collapse:collapse;"><tr>           
<td style="border-width:1px;border-style:solid;"><span>No.</span></td>
<td style="border-width:1px;border-style:solid;"><span>Question</span></td>
<td style="border-width:1px;border-style:solid;"><span>dislike</span></td>
<td style="border-width:1px;border-style:solid;"><span>normal</span></td>
<td style="border-width:1px;border-style:solid;"><span>like</span></td>
<td style="border-width:1px;border-style:solid;"><span>vry likes</span></td></tr><tr>
<td style="border-width:1px;border-style:solid;"><span>1</span></td>
<td style="border-width:1px;border-style:solid;"><span>question 1</span></td>
<td style="border-width:1px;border-style:solid;">
    <input id="rBtn_1_0" type="radio" name="rBtn1" value="rBtn_1_0" value="0" /></td>
<td style="border-width:1px;border-style:solid;">
    <input id="rBtn_1_1" type="radio" name="rBtn1" value="rBtn_1_1" value="1" /></td>
<td style="border-width:1px;border-style:solid;">
    <input id="rBtn_1_2" type="radio" name="rBtn1" value="rBtn_1_2" checked="checked" value="2" /></td>
<td style="border-width:1px;border-style:solid;">
    <input id="rBtn_1_3" type="radio" name="rBtn1" value="rBtn_1_3" value="3" /></td></tr></table>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

各空 2024-08-03 03:07:26

如果生成的单选按钮组的名称足够可预测,您可以通过检查 Request.Form 集合来获取它们的值。 假设组名称为 rBtn1、rBtn2 等,则发布数据将类似于 rBtn1=6&rBtn2=7。 这意味着您可以这样做:

Dim i as Integer
Dim score as Integer = 0
For i = 1 To expectedNumRows
    score += CInt(Request.Form("rBtn" & i)) 
Next

这将帮助您解决之前生成的控件不再存在的问题。 您应该在调试器中浏览并检查 Request.Form 集合,以便熟悉其中的内容。

(如果我的 VB.NET 不正确,我很抱歉;我习惯了 C#)

If the names of the generated radio button groups are predictable enough, you could get their values by inspecting the Request.Form collection. Assuming the group names are rBtn1, rBtn2, etc, the post data will look something like rBtn1=6&rBtn2=7. That means you can do this:

Dim i as Integer
Dim score as Integer = 0
For i = 1 To expectedNumRows
    score += CInt(Request.Form("rBtn" & i)) 
Next

This will help you work around the fact that the controls that were generated before no-longer exist. You should poke around in the debugger and inspect the Request.Form collection so you can get familiar with what's in there.

(my apologies if my VB.NET is incorrect; I'm used to C#)

土豪我们做朋友吧 2024-08-03 03:07:26

感谢雅各布的解决方案。

我可以通过对 ID 分配进行一些修改来计算分数。

我在 id 后面添加了它的值,因为生成的值与视图源中显示的 ID 相同

rBtn.ID = "rBtn[" & rowCnt & "][" & colCnt & "]_" & value (eg. rBtn[1][0]_2 )

然后,我使用子字符串来获取并计算分数,如下面的 subCalculateScore 函数所示:

 Private Function subCalulateScore() As Integer
    Dim score As Integer = 0
    Dim expectedNumRows As Integer = Me.qsNum.Text
    For i As Integer = 1 To expectedNumRows
        Dim strBtn As String = Request.Form("rBtn" & i)
        If Not strBtn Is Nothing Then
            If strBtn.LastIndexOf("_") <> -1 Then
                Dim strScore As String = strBtn.Substring(strBtn.LastIndexOf("_") + 1)
                score += CInt(strScore)
            End If
        End If
    Next

    Return score
End Function

哈哈..听起来像这是一个糟糕的方法:p

再次感谢你的帮助,雅各布。

随时欢迎任何其他解决方案^^

Thank you Jacob for his solution.

I am able to calculate the score by making some modification for the ID assignment.

I added its value at the back of the id since the value generated is the same with the ID as shown in the view source

rBtn.ID = "rBtn[" & rowCnt & "][" & colCnt & "]_" & value (eg. rBtn[1][0]_2 )

Then, i used substring to get and calculate the score as shown in the subCalculateScore function below:

 Private Function subCalulateScore() As Integer
    Dim score As Integer = 0
    Dim expectedNumRows As Integer = Me.qsNum.Text
    For i As Integer = 1 To expectedNumRows
        Dim strBtn As String = Request.Form("rBtn" & i)
        If Not strBtn Is Nothing Then
            If strBtn.LastIndexOf("_") <> -1 Then
                Dim strScore As String = strBtn.Substring(strBtn.LastIndexOf("_") + 1)
                score += CInt(strScore)
            End If
        End If
    Next

    Return score
End Function

Haha.. sound like a lousy way to do it :p

Once again, thanks for your help, Jacob.

Always welcome for any other solution ^^

〗斷ホ乔殘χμё〖 2024-08-03 03:07:26

我昨天发现,通过在 loadviewstateevent 触发后立即加载控制树,您实际上可以使您的应用程序像平常一样工作。 如果您重写 loadviewstate 事件,调用 mybase.loadviewstate,然后在其后面放置您自己的代码以重新生成控件,则这些控件的值将在页面加载时可用。 在我的一个应用程序中,我使用视图状态字段来保存可用于重新创建这些控件的 ID 或数组信息。

Protected Overrides Sub LoadViewState(ByVal savedState As Object)
    MyBase.LoadViewState(savedState)
    If IsPostBack Then
        CreateMyControls()
    End If
End Sub

I figured out yesterday that you can actually make your app work like normal by loading the control tree right after the loadviewstateevent is fired. if you override the loadviewstate event, call mybase.loadviewstate and then put your own code to regenerate the controls right after it, the values for those controls will be available on page load. In one of my apps I use a viewstate field to hold the ID or the array info that can be used to recreate those controls.

Protected Overrides Sub LoadViewState(ByVal savedState As Object)
    MyBase.LoadViewState(savedState)
    If IsPostBack Then
        CreateMyControls()
    End If
End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文