Pregunta

Estoy tratando de obtener un ASP.NET 3.5 GridView para mostrar un valor seleccionado como cadena cuando se muestra, y para mostrar un DropDownList que me permite elegir un valor de una lista de opciones dada cuando se edita. Parece bastante simple?

Mi vista de cuadrícula se ve así (simplificada):

<asp:GridView ID="grvSecondaryLocations" runat="server" 
              DataKeyNames="ID" OnInit="grvSecondaryLocations_Init" 
              OnRowCommand="grvSecondaryLocations_RowCommand" 
              OnRowCancelingEdit="grvSecondaryLocations_RowCancelingEdit"
              OnRowDeleting="grvSecondaryLocations_RowDeleting"
              OnRowEditing="grvSecondaryLocations_RowEditing" 
              OnRowUpdating="grvSecondaryLocations_RowUpdating"  >
<Columns>
    <asp:TemplateField>
         <ItemTemplate>
              <asp:Label ID="lblPbxTypeCaption" runat="server" 
                                 Text='<%# Eval("PBXTypeCaptionValue") %>' />
         </ItemTemplate>
         <EditItemTemplate>
                      <asp:DropDownList ID="ddlPBXTypeNS" runat="server" 
                               Width="200px" 
                               DataTextField="CaptionValue" 
                               DataValueField="OID" />
         </EditItemTemplate>
    </asp:TemplateField>
</asp:GridView>

La cuadrícula se muestra OK cuando no está en modo de edición: el tipo de PBX seleccionado muestra su valor en el control asp: Label. No hay sorpresa allí.

Cargo la lista de valores para DropDownList en un miembro local llamado _pbxTypes en el evento OnLoad del formulario. Verifiqué esto: funciona, los valores están ahí.

Ahora mi desafío es: cuando la cuadrícula entra en modo de edición para una fila particular, necesito vincular la lista de PBX almacenadas en _pbxTypes .

Bastante simple, pensé: simplemente tome el objeto de la lista desplegable en el evento RowEditing y adjunte la lista:

protected void grvSecondaryLocations_RowEditing(object sender, GridViewEditEventArgs e)
{
    grvSecondaryLocations.EditIndex = e.NewEditIndex;

    GridViewRow editingRow = grvSecondaryLocations.Rows[e.NewEditIndex];

    DropDownList ddlPbx = (editingRow.FindControl("ddlPBXTypeNS") as DropDownList);
    if (ddlPbx != null)
    {
        ddlPbx.DataSource = _pbxTypes;
        ddlPbx.DataBind();
    }

    .... (more stuff)
}

El problema es que nunca recibo nada de la llamada FindControl , parece que ddlPBXTypeNS no existe (o no se puede encontrar).

¿Qué me estoy perdiendo? Debe ser algo realmente estúpido ... pero hasta ahora, todo mi Google, leer sobre los controles de GridView y preguntar amigos no ha ayudado.

¿Quién puede detectar el eslabón perdido? ;-)

¿Fue útil?

Solución

Muy fácil ... Lo estás haciendo mal, porque en ese caso el control no está allí:

protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow && 
        (e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
    { 
        // Here you will get the Control you need like:
        DropDownList dl = (DropDownList)e.Row.FindControl("ddlPBXTypeNS");
    }
}

Es decir, solo será válido para un DataRow (la fila real con datos), y si está en modo Editar ... porque solo edita uno remar a la vez. El e.Row.FindControl (" ddlPBXTypeNS ") solo encontrará el control que desee.

Otros consejos

Estoy usando un ListView en lugar de un GridView en 3.5. Cuando el usuario quiere editar, he establecido el elemento seleccionado del menú desplegable en el valor existente de esa columna para el registro. Puedo acceder al menú desplegable en el evento ItemDataBound. Aquí está el código:

protected void listViewABC_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    // This stmt is used to execute the code only in case of edit 
    if (((ListView)(sender)).EditIndex != -1 && ((ListViewDataItem)(e.Item)).DisplayIndex == ((ListView)(sender)).EditIndex)
    {
        ((DropDownList)(e.Item.FindControl("ddlXType"))).SelectedValue = ((MyClass)((ListViewDataItem)e.Item).DataItem).XTypeId.ToString();
        ((DropDownList)(e.Item.FindControl("ddlIType"))).SelectedValue = ((MyClass)((ListViewDataItem)e.Item).DataItem).ITypeId.ToString();
    }
}
protected void grvSecondaryLocations_RowEditing(object sender, GridViewEditEventArgs e)  
{  
    grvSecondaryLocations.EditIndex = e.NewEditIndex;  

    DropDownList ddlPbx = (DropDownList)(grvSecondaryLocations.Rows[grvSecondaryLocations.EditIndex].FindControl("ddlPBXTypeNS"));
    if (ddlPbx != null)  
    {  
        ddlPbx.DataSource = _pbxTypes;  
        ddlPbx.DataBind();  
    }  

    .... (more stuff)  
}

La respuesta de balexandre comprobada funciona muy bien. Pero, creará un problema si se adapta a otras situaciones.

Lo usé para cambiar el valor de dos controles de etiqueta: lblEditModifiedBy y lblEditModifiedOn , cuando estaba editando una fila, de modo que el ModifiedBy correcto y ModifiedOn se guardaría en la base de datos en 'Actualizar'.

Cuando hice clic en el botón 'Actualizar', en el evento RowUpdating mostraba los nuevos valores que ingresé en la lista OldValues ??. Necesitaba los verdaderos "viejos valores" como valores Original_ al actualizar la base de datos. (Hay un ObjectDataSource adjunto al GridView ).

La solución a esto es usar el código de balexandre, pero de forma modificada en el evento gv_DataBound :

protected void gv_DataBound(object sender, EventArgs e)
{
    foreach (GridViewRow gvr in gv.Rows)
    {
        if (gvr.RowType == DataControlRowType.DataRow && (gvr.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
        {
            // Here you will get the Control you need like:
            ((Label)gvr.FindControl("lblEditModifiedBy")).Text = Page.User.Identity.Name;
            ((Label)gvr.FindControl("lblEditModifiedOn")).Text = DateTime.Now.ToString();
        }
    }
}

Puede usar SelectedValue:

<EditItemTemplate>
    <asp:DropDownList ID="ddlPBXTypeNS"
                      runat="server"
                      Width="200px"
                      DataSourceID="YDS"
                      DataTextField="CaptionValue"
                      DataValueField="OID"
                      SelectedValue='<%# Bind("YourForeignKey") %>' />
    <asp:YourDataSource ID="YDS" ...../>
</EditItemTemplate>
 <asp:GridView ID="GridView1" runat="server" PageSize="2" AutoGenerateColumns="false"
            AllowPaging="true" BackColor="White" BorderColor="#CC9966" BorderStyle="None"
            BorderWidth="1px" CellPadding="4" OnRowEditing="GridView1_RowEditing" OnRowUpdating="GridView1_RowUpdating"
            OnPageIndexChanging="GridView1_PageIndexChanging" OnRowCancelingEdit="GridView1_RowCancelingEdit"
            OnRowDeleting="GridView1_RowDeleting">
            <FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
            <RowStyle BackColor="White" ForeColor="#330099" />
            <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="#663399" />
            <PagerStyle BackColor="#FFFFCC" ForeColor="#330099" HorizontalAlign="Center" />
            <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="#FFFFCC" />
            <Columns>
            <asp:TemplateField HeaderText="SerialNo">
            <ItemTemplate>
            <%# Container .DataItemIndex+1 %>.&nbsp
            </ItemTemplate>
            </asp:TemplateField>
                <asp:TemplateField HeaderText="RollNo">
                    <ItemTemplate>
                        <%--<asp:Label ID="lblrollno" runat="server" Text='<%#Eval ("RollNo")%>'></asp:Label>--%>
                        <asp:TextBox ID="txtrollno" runat="server" Text='<%#Eval ("RollNo")%>'></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="SName">
                    <ItemTemplate>
                    <%--<asp:Label ID="lblsname" runat="server" Text='<%#Eval("SName")%>'></asp:Label>--%>
                        <asp:TextBox ID="txtsname" runat="server" Text='<%#Eval("SName")%>'> </asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="C">
                    <ItemTemplate>
                    <%-- <asp:Label ID="lblc" runat="server" Text='<%#Eval ("C") %>'></asp:Label>--%>
                        <asp:TextBox ID="txtc" runat="server" Text='<%#Eval ("C") %>'></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Cpp">
                    <ItemTemplate>
                    <%-- <asp:Label ID="lblcpp" runat="server" Text='<%#Eval ("Cpp")%>'></asp:Label>--%>
                       <asp:TextBox ID="txtcpp" runat="server" Text='<%#Eval ("Cpp")%>'> </asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Java">
                    <ItemTemplate>
                       <%--  <asp:Label ID="lbljava" runat="server" Text='<%#Eval ("Java")%>'> </asp:Label>--%>
                        <asp:TextBox ID="txtjava" runat="server" Text='<%#Eval ("Java")%>'> </asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Edit" ShowHeader="False">
                    <EditItemTemplate>
                        <asp:LinkButton ID="lnkbtnUpdate" runat="server" CausesValidation="true" Text="Update"
                            CommandName="Update"></asp:LinkButton>
                        <asp:LinkButton ID="lnkbtnCancel" runat="server" CausesValidation="false" Text="Cancel"
                            CommandName="Cancel"></asp:LinkButton>
                    </EditItemTemplate>
                    <ItemTemplate>
                        <asp:LinkButton ID="btnEdit" runat="server" CausesValidation="false" CommandName="Edit"
                            Text="Edit"></asp:LinkButton>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:CommandField HeaderText="Delete" ShowDeleteButton="True" ShowHeader="True" />
                <asp:CommandField HeaderText="Select" ShowSelectButton="True" ShowHeader="True" />
            </Columns>
        </asp:GridView>
        <table>
            <tr>
                <td>
                    <asp:Label ID="lblrollno" runat="server" Text="RollNo"></asp:Label>
                    <asp:TextBox ID="txtrollno" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblsname" runat="server" Text="SName"></asp:Label>
                    <asp:TextBox ID="txtsname" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblc" runat="server" Text="C"></asp:Label>
                    <asp:TextBox ID="txtc" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblcpp" runat="server" Text="Cpp"></asp:Label>
                    <asp:TextBox ID="txtcpp" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lbljava" runat="server" Text="Java"></asp:Label>
                    <asp:TextBox ID="txtjava" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                    <asp:Button ID="Submit" runat="server" Text="Submit" OnClick="Submit_Click" />
                    <asp:Button ID="Reset" runat="server" Text="Reset" OnClick="Reset_Click" />
                </td>
            </tr>
        </table>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top