0

我定义了以下完美填充的gridview:

    <asp:GridView runat="server" ID="chargeDetail" AutoGenerateColumns="false" DataKeyNames="LineItemNumber,DetailId,IsParking" CellSpacing="0" CellPadding="6"
     HorizontalAlign="Center" EnableViewState="true" ShowFooter="true">
        <Columns>
            <asp:BoundField DataField="StudentID" HeaderText="Student ID" ReadOnly="True" ItemStyle-HorizontalAlign="Center" />
            <asp:BoundField DataField="StudentName" HeaderText="Name" ReadOnly="true" />
            <asp:BoundField DataField="CampusName" HeaderText="Campus" ReadOnly="true" />
            <asp:TemplateField HeaderText="Description" ItemStyle-HorizontalAlign="Center">
                <ItemTemplate>
                    <asp:Label runat="server" ID="LineItemDetailLabel" Text='<%# IIf(Eval("Mandatory") = "1", Eval("LineItemDetail") + " *", Eval("LineItemDetail")) %>' />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Item Cost" ItemStyle-HorizontalAlign="Center">
                <ItemTemplate>
                    $<asp:Label runat="server" ID="LineItemCostLabel" Text='<%# Eval("LineItemCost") %>' />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Options" ItemStyle-HorizontalAlign="Center">
                <ItemTemplate>
                    <asp:Label runat="server" ID="lblOptionsAvailable" 
                     Text='<%# IIf(Eval("AttributesAvailable") = "1", "Options will be available to select on the next screen.", "No options available.") %>' />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Pay Now" ItemStyle-HorizontalAlign="Center" FooterText="Total:">
                <ItemTemplate>
                    <asp:Checkbox runat="server" ID="cbLineItemSelected" Checked='<%# IIf(Eval("Selected") = "1", "True", "False") %>'
                     Enabled='<%# IIf(Eval("Mandatory") = "1", "False", "True") %>' AutoPostBack="True" OnCheckedChanged="cbLineItemSelected_CheckedChanged" />
                </ItemTemplate>
                <FooterStyle Font-Bold="True" HorizontalAlign="Right" />
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Total">
                <ItemTemplate>
                    $<asp:Label runat="server" ID="lblLineTotalCost" Text='<%# IIf(Eval("Selected") = "1", Eval("LineItemCost"), "0.00") %>' />
                </ItemTemplate>
                <FooterTemplate>
                    $<asp:Label runat="server" ID="lblTotal" />
                </FooterTemplate>
                <FooterStyle Font-Bold="True" />
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

在 HeaderText="Options" 的 TemplateField 中,我需要能够创建可变数量的下拉列表。对于学校可能收取的每项费用,它们可以具有任意数量的相关属性。例如,T恤费可能需要收集尺码和颜色,并且每个属性可能有多个选项。

现在,您可以看到我有一个正确填充的标签,但我需要能够创建两个下拉列表,在本例中为大小和颜色,以便父母在选中要包含的框时可以指定它们这笔费用在他们的收费中。您会注意到,在“立即付款”列中,复选框有一个 OnCheckedChanged 事件,该事件当前更新了页脚行中的总计列和总体总计。

理想情况下,我希望该事件在选中时填充下拉列表,以便父母可以进行选择。我还需要知道如何处理从这些下拉列表中返回的帖子,以便正确记录选择。

从我能找到的情况来看,我猜我需要创建一个嵌套的网格视图,我可以在其中放置下拉列表,但我找不到任何示例来为我指明如何使其工作的正确方向。我可以轻松地从后面的代码中填充下拉列表,如果指向正确的方向,则在父母输入数据时访问数据。只需要一点方向或更简单的方法。

提前致谢!

4

1 回答 1

0

好的,我想出了一个似乎可行的解决方案。在 gridview 定义中,我嵌套了另一个 gridview,其中包含下拉列表,如下所示:

        <asp:TemplateField HeaderText="Options" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:GridView runat="server" ID="gvOptions" AutoGenerateColumns="False" DataKeyNames="AttributeId" HorizontalAlign="center" EnableViewState="true"
                    GridLines="None" EmptyDataText="No available options." ShowHeader="False">
                    <Columns>
                        <asp:BoundField DataField="Description" ReadOnly="true" ItemStyle-HorizontalAlign="Center" />
                        <asp:TemplateField>
                            <ItemTemplate>
                                <asp:DropDownList runat="server" ID="ddlOptionSelection" DataTextField="Description" DataValueField="OptionId"
                                    EnableViewState="true" AutoPostBack="true" OnSelectedIndexChanged="ddlOptionSelection_SelectedIndexChanged">
                                </asp:DropDownList>
                            </ItemTemplate>
                        </asp:TemplateField>
                    </Columns>
                </asp:GridView>
            </ItemTemplate>
        </asp:TemplateField>

挑战在于弄清楚如何将所有内容联系在一起,因为嵌套网格视图中的数据依赖于父网格视图中的数据键。父级的 RowDataBound 事件找到子 gridview 并填充下拉列表,如下所示(gvOptions 是子级,chargeDetail 是父级):

Protected Sub chargeDetail_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles chargeDetail.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim gv As GridView = DirectCast(e.Row.FindControl("gvOptions"), GridView)
        Dim cb As CheckBox = DirectCast(e.Row.FindControl("cbLineItemSelected"), CheckBox)
        Dim lineItem As String = chargeDetail.DataKeys(e.Row.RowIndex).Values("LineItemNumber")
        gv.DataSource = GetOptions(chargeDetail.DataKeys(e.Row.RowIndex).Values("DetailId"))
        gv.DataBind()

        Dim gridLineCount As Integer = gv.Rows.Count()
        Dim gridWorkingRow As Integer

        For gridWorkingRow = 0 To gridLineCount - 1
            Dim ddl As DropDownList = gv.Rows(gridWorkingRow).FindControl("ddlOptionSelection")
            Dim AttribId As Integer = gv.DataKeys(gridWorkingRow).Values("AttributeId")
            ddl.DataSource = PopulateOptions(AttribId)
            ddl.DataBind()
            ddl.SelectedValue = GetSelectedValue(AttribId, lineItem)

            If cb.Checked Then
                ddl.Enabled = True
            Else
                ddl.Enabled = False
            End If
        Next gridWorkingRow
    End If
End Sub

当其中一个下拉列表更改时,将触发以下内容。我发现根据数据在数据库中的存储方式,重新发送所有选项更容易,因为属性:选项对被连接起来存储在单个字段中:

Protected Sub ddlOptionSelection_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
    Dim ddlSender As DropDownList = DirectCast(sender, DropDownList)
    Dim row As GridViewRow = DirectCast(ddlSender.NamingContainer, GridViewRow)
    Dim gvOption As GridView = DirectCast(row.NamingContainer, GridView)
    Dim chargeDetailRow As GridViewRow = DirectCast(gvOption.Parent.Parent, GridViewRow)
    Dim LineItemNumber As Integer = CInt(chargeDetail.DataKeys(chargeDetailRow.RowIndex).Values("LineItemNumber"))

    Dim gridLineCount As Integer = gvOption.Rows.Count()
    Dim gridWorkingRow As Integer
    Dim OptionString As String = ""

    For gridWorkingRow = 0 To gridLineCount - 1
        Dim ddl As DropDownList = gvOption.Rows(gridWorkingRow).FindControl("ddlOptionSelection")
        Dim AttribId As String = gvOption.DataKeys(gridWorkingRow).Values("AttributeId")

        If gridWorkingRow = gridLineCount - 1 Then
            OptionString = OptionString + AttribId + ":" + ddl.SelectedValue
        Else
            OptionString = OptionString + AttribId + ":" + ddl.SelectedValue + ","
        End If
    Next gridWorkingRow

    Dim PortalConn As New SqlConnection
    PortalConn.ConnectionString = ConfigurationManager.ConnectionStrings("PortalConnStr").ConnectionString
    PortalConn.Open()

    Dim WriteBackSQL As New SqlCommand("sp_schedulePickup_UpdateOption", PortalConn)
    WriteBackSQL.CommandType = Data.CommandType.StoredProcedure
    WriteBackSQL.Parameters.Add(New SqlParameter("@SessionID", Session.SessionID.ToString()))
    WriteBackSQL.Parameters.Add(New SqlParameter("@LineItemNumber", LineItemNumber))
    WriteBackSQL.Parameters.Add(New SqlParameter("@Option", OptionString))

    Dim returnStatus As Integer
    Dim rsReturn As SqlDataReader = WriteBackSQL.ExecuteReader()
    Do While rsReturn.Read()
        returnStatus = rsReturn("ReturnStatus")
    Loop
    rsReturn.Close()
    rsReturn = Nothing

    PortalConn.Close()
    PortalConn = Nothing

    chargeDetail.DataSource = GetChargeDetails()
    chargeDetail.DataBind()
    getTotal()
End Sub
于 2012-06-12T16:20:48.670 回答