Получить значение из DropDownList во вложенном GridView на RowCommand

У меня есть вложенный GridView (GvMP_Summary_Items). Каждая строка содержит DropDownList. DropDownList ограничен в событии RowDataBound вложенного GridView.

Каждая строка также содержит 1 кнопку. Нажав эту кнопку на событии 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

Я даже включил TextBox в строку GridView, значение по умолчанию пуста "". Хотя в строке, если что-то введено, событие RowCommand возвращает значение с запятой (,) перед ним.

Это доказывает, что я собираю правильную строку и могу получить значение из TextBox, но не DropDownList.

Есть ли что-то, что мне не хватает? Почему я могу вернуть значение, введенное в TextBox, но не выбранное значение DropDownList? Также почему запятая (,) перед значением TextBox?

Примечание: В приведенном выше коде кода код написан с использованием VB, поэтому ответы в VB по С#, но я могу принять оба.

Ответы

Ответ 1

Важные вещи:

  • Связать родительский GridView в Page_Load.
  • Связать дочерний GridView в родительском GridView Событие RowDataBound
  • Привязать DropDownList к дочернему элементу GridView Событие RowDataBound
  • Добавьте CommandName к кнопке, которая находится внутри дочернего элемента GridView
  • Наконец, в событии RowCommand дочернего GridView
    • Получить дочерний GridView row
    • Затем найдите все элементы управления внутри дочернего GridView из дочернего GridView строка

Я не очень осведомлен о VB.NET, поэтому я добавил пример (С#) из Nested 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>

Code-Behind (.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  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  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  button clicked
protected void GridView_Inner_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // get Inner GridView  clicked row
    GridViewRow InnerGridViewRow = (GridViewRow)(((Control)e.CommandSource).NamingContainer);

    // get Inner GridView  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  Selected Value is " + DropDownListValue +
                            "<br />TextBox  Entered Value is " + TextBoxValue;
    }
}

Демо-изображение:

введите описание изображения здесь Примечание. Над DropDownList выбирает выбранное значение, а не текст.

Ответ 2

Это можно сделать очень легко, возвращая CommandSource из RowCommand назад к кнопке, а затем получите правильную строку. Когда у вас есть строка, вы можете использовать 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

Код был переведен с С# с помощью транслятора кода, поэтому он может быть не точным на 100%.

С#

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;
}

Вам необходимо привязать данные к GridView и DropDownLists в IsPostBack, в противном случае данные будут отскакивать до DDL на каждом PostBack и потерянное значение