asp.net - Edición de fila de Gridview: unión dinámica a DropDownList
drop-down-menu dynamic-binding (6)
Estoy usando un ListView en lugar de un GridView en 3.5. Cuando el usuario desea 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();
}
}
Estoy tratando de obtener un ASP.NET 3.5 GridView para mostrar un valor seleccionado como una cadena cuando se muestra, y para mostrar una DropDownList que me permite elegir un valor de una lista dada de opciones cuando se edita. Parece lo suficientemente simple?
Mi vista de grilla 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 asp: control de etiqueta. No es sorpresa allí.
_pbxTypes
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 grilla entra en modo de edición para una fila en 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 obtengo nada de la llamada FindControl
, parece que el ddlPBXTypeNS
no existe (o no se puede encontrar).
¿¿Qué me estoy perdiendo?? Debe ser algo realmente estúpido ... pero hasta ahora, todo mi Google, leyendo en los controles de GridView, y pidiéndole a mis amigos no ha ayudado.
¿Quién puede detectar el eslabón perdido? ;-)
La respuesta comprobada de balexandre 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, para que el ModifiedBy y ModifiedOn
correctos se lblEditModifiedOn
en el db en ''Actualizar''.
Cuando hice clic en el botón ''Actualizar'', en el evento RowUpdating
mostró los nuevos valores que OldValues
en la lista OldValues
. Necesitaba los verdaderos "valores antiguos" como valores Original_ al actualizar la base de datos. (Hay un ObjectDataSource
adjunto a GridView
).
La solución a esto es usar el código de balexandre, pero en una 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();
}
}
}
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 una DataRow
(la fila real con datos) y si está en el modo de edición ... porque solo edita una fila a la vez. El e.Row.FindControl("ddlPBXTypeNS")
solo encontrará el control que desee.
Puedes 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 %>. 
</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>
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)
}