在 RowCommand 中检索嵌套 GridView 中 DropDownList 的值

14

我有一个嵌套的 GridView(GvMP_Summary_Items),每一行都包含一个 DropDownList。DropDownList 在嵌套 GridView 的 RowDataBound 事件上绑定。

每一行还包含一个按钮。在 RowCommand 事件中按下此按钮后,我想找到 DropDownList 的当前选定值,以便稍后在代码中使用它。

我现有的代码只会获取每行 DropDownList 的默认值,这个默认值当前设置为每行的 0

以下是 RowCommand 事件:

Protected Sub GvMP_Summary_Items_RowCommand(sender As Object, e As GridViewCommandEventArgs)

  Dim lb As ImageButton = CType(e.CommandSource, ImageButton)
  Dim gvRow As GridViewRow = lb.BindingContainer //Getting current row to get index       

  Dim GvMP_Summary_Items As GridView = CType(gvRow.FindControl("GvMP_Summary_Items"), GridView)

  Dim intMPItem_Qty As Integer = CType(gvRow.FindControl("cboMPItem_Qty"), DropDownList).SelectedValue
  Dim strMPItem_Qty As String = CType(gvRow.FindControl("txtMPItem_Qty"), TextBox).Text

End Sub

我甚至在GridView的行中包括了一个默认值为空字符串""的TextBox。尽管在该行上如果输入了某些内容,on RowCommand事件会将其带回带一个逗号(,)开头的值。

这证明我正在选择正确的行,并且可以从TextBox中检索到值,但无法检索DropDownList的选定值。

我是否遗漏了什么?为什么我可以返回TextBox中输入的值而不是DropDownList的选定值?同时为什么在TextBox值前面有逗号(,)?

注意:以上代码是使用VB编写的,因此可以使用VB或C#进行答复,但两者都可以接受。


你是如何填充下拉列表的?有可能你在每次回发时清除并重新填充它,将其重置为默认值吗? - SBFrancies
2个回答

3

重要事项:

  1. Page_Load方法中绑定父GridView

  2. 在父GridViewRowDataBound事件中绑定子GridView

  3. 在子GridViewRowDataBound事件中绑定DropDownList

  4. 在子GridView内部的按钮中添加CommandName

  5. 最后,在子GridView的RowCommand事件中:

    • 获取子GridView的行
    • 然后从子GridView的行中查找所有控件

我不是很了解VB.NET,所以我添加了一个嵌套GridView和RowCommand事件的示例(希望OP可以在VB.NET中使用):

HTML代码(.Aspx):

<form id="form1" runat="server">

<asp:GridView ID="GridView_Outer" OnRowDataBound="GridView_Outer_RowDataBound" AutoGenerateColumns="false" runat="server">
    <Columns>
        <asp:TemplateField HeaderText="Outer Column1">
            <ItemTemplate>
                <asp:Label ID="Label_Outer" runat="server" Text='<%# Eval("Label_Outer") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Outer Column2">
            <ItemTemplate>
                <asp:GridView ID="GridView_Inner" OnRowDataBound="GridView_Inner_RowDataBound" OnRowCommand="GridView_Inner_RowCommand" AutoGenerateColumns="false" runat="server">
                    <Columns>
                        <asp:TemplateField HeaderText="Inner Column1">
                            <ItemTemplate>
                                <asp:Label ID="Label_Inner" runat="server" Text='<%# Eval("Label_Inner") %>'></asp:Label>
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField HeaderText="Inner Column2">
                            <ItemTemplate>
                                <asp:TextBox ID="TextBox_Inner" Text='<%# Eval("TextBox_Inner") %>' runat="server"></asp:TextBox>
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField HeaderText="Inner Column3">
                            <ItemTemplate>
                                <asp:DropDownList ID="DropDownList_Inner" runat="server"></asp:DropDownList>
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField HeaderText="Inner Column4">
                            <ItemTemplate>
                                <asp:Button ID="Button_Inner" runat="server" CommandName="BtnInnerCmd" Text="Inner Button" />
                            </ItemTemplate>
                        </asp:TemplateField>
                    </Columns>
                </asp:GridView>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<br />
<asp:Label ID="Label_Result" runat="server"></asp:Label>

</form>

代码后端 (.Aspx.cs):

DataTable TempDT = new DataTable();

protected void Page_Load(object sender, EventArgs e)
{
    CreateDataTable();

    if (!IsPostBack)
    {
        GridView_Outer.DataSource = TempDT;
        GridView_Outer.DataBind();
    }
}

// create DataTable
public void CreateDataTable()
{
    TempDT = new DataTable();
    TempDT.Columns.Add("Label_Outer");
    TempDT.Columns.Add("Label_Inner");
    TempDT.Columns.Add("TextBox_Inner");

    TempDT.Rows.Add("OuterLabel", "InnerLabel", "");
    TempDT.Rows.Add("OuterLabel", "InnerLabel", "");

    // store DataTable into ViewState to prevent data loss on PostBack
    ViewState["DT"] = TempDT;
}

// Calls Outer GridView on Data Binding
protected void GridView_Outer_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // check if gridview row is not in edit mode
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Get Outer GrridView 's controls
        Label Label_Outer = (Label)e.Row.FindControl("Label_Outer");
        GridView GridView_Inner = (GridView)e.Row.FindControl("GridView_Inner");

        // get DataTable from ViewState and set to Inner GridView
        GridView_Inner.DataSource = (DataTable)ViewState["DT"];
        GridView_Inner.DataBind();
    }
}

// Calls Inner GridView on Data Binding
protected void GridView_Inner_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // check if gridview row is not in edit mode
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Get Outer GrridView 's controls
        DropDownList DropDownList_Inner = (DropDownList)e.Row.FindControl("DropDownList_Inner");

        // Create a DataTable to Bind data for DropDownlist
        DataTable TempDDLDT = new DataTable();
        TempDDLDT.Columns.Add("ItemText");
        TempDDLDT.Columns.Add("ItemValue");

        TempDDLDT.Rows.Add("ItemText1", "ItemValue1");
        TempDDLDT.Rows.Add("ItemText2", "ItemValue2");

        // bind DataTable to the DropDownList
        DropDownList_Inner.DataSource = TempDDLDT;
        DropDownList_Inner.DataTextField = "ItemText";
        DropDownList_Inner.DataValueField = "ItemValue";
        DropDownList_Inner.DataBind();
    }
}

// Calls when Inner GridView 's button clicked
protected void GridView_Inner_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // get Inner GridView 's clicked row
    GridViewRow InnerGridViewRow = (GridViewRow)(((Control)e.CommandSource).NamingContainer);

    // get Inner GridView 's controls from clicked row
    TextBox TextBox_Inner = (TextBox)InnerGridViewRow.FindControl("TextBox_Inner");
    DropDownList DropDownList_Inner = (DropDownList)InnerGridViewRow.FindControl("DropDownList_Inner");

    // check if correct button is clicked
    if (e.CommandName == "BtnInnerCmd")
    {
        string DropDownListValue = DropDownList_Inner.SelectedValue;
        string TextBoxValue = TextBox_Inner.Text;

        Label_Result.Text = "DropDownList 's Selected Value is " + DropDownListValue +
                            "<br />TextBox 's Entered Value is " + TextBoxValue;
    }
}

演示图片:

输入图像说明 注意: 上述下拉列表框选择的是所选值而不是文本。


2

通过将RowCommandCommandSource转换为按钮,然后从中获取正确的行,可以很容易地完成此操作。一旦获得了行,就可以使用FindControl定位DropDownList。这适用于每个嵌套项的级别,也适用于顶级控件。

VB

Protected Sub GMP_Summary_Items_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)

    'cast the commandsource back to a button
    Dim btn As Button = CType(e.CommandSource,Button)

    'get the current gridviewrow from the button namingcontainer
    Dim row As GridViewRow = CType(btn.NamingContainer,GridViewRow)

    'use findcontrol to locate the dropdownlist in that row
    Dim ddl As DropDownList = CType(row.FindControl("cboMPItem_Qty"),DropDownList)

    'show the selected value of the dropdownlist
    Label1.Text = ddl.SelectedValue

End Sub

这段代码是使用代码翻译器从C#翻译而来的,因此可能不是100%准确。

C#

protected void GMP_Summary_Items_RowCommand(object sender, GridViewCommandEventArgs e)
{
    //cast the commandsource back to a button
    Button btn = e.CommandSource as Button;

    //get the current gridviewrow from the button namingcontainer
    GridViewRow row = btn.NamingContainer as GridViewRow;

    //use findcontrol to locate the dropdownlist in that row
    DropDownList ddl = row.FindControl("cboMPItem_Qty") as DropDownList;

    //show the selected value of the dropdownlist
    Label1.Text = ddl.SelectedValue;
}

您需要在IsPostBack检查中绑定数据到GridView和DropDownLists,否则数据将在每次PostBack时重新绑定到DDL上,选择的值会丢失。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接