Cómo: Permitir que los usuarios editen elementos en controles DataList de servidor Web

Actualización: noviembre 2007

Puede permitir que los usuarios editen elementos individuales en el control DataList de servidor Web. Cuando un elemento individual se establece en el modo de edición, los valores que se pueden modificar aparecen por lo general en cuadros de texto o en otros controles en los que los usuarios pueden realizar sus cambios.

Para permitir que los usuarios editen elementos en un control DataList

  1. Establezca la propiedad DataKeyField del control DataList en el nombre del campo de los datos que contiene la clave principal.

  2. Cree una propiedad de plantilla ItemTemplate (si ya la está utilizando, cree AlternatingItemTemplate) y, a continuación, agregue un control Button de servidor Web. Establezca la propiedad CommandName del botón en edit.

    Nota:

    Puede utilizar un control LinkButton o ImageButton en cualquier paso que requiera un control Button de servidor Web.

  3. Cree una propiedad de plantilla EditItemTemplate para el control DataList que incluya lo siguiente:

    • Controles de todos los valores que los usuarios puedan modificar. Por ejemplo, incluya controles TextBox para todos los datos de caracteres y datos numéricos. Utilice el método Eval declarativo para especificar a qué campo está enlazado cada control, como en este ejemplo:

      <asp:TextBox ID="TextBox1" 
      
        Text='<%# Eval("ProductName") %>' />
      
    • Un control Button con su propiedad Text establecida en "Actualizar" y su propiedad CommandName establecida en update (con distinción entre mayúsculas y minúsculas).

    • Un control Button con su propiedad Text establecida en "Cancelar" y su propiedad CommandName establecida en cancel.

      El botón Actualizar permitirá a los usuarios especificar que han finalizado el proceso de edición y que van a guardar los cambios. El botón Cancelar les permitirá abandonar el proceso de edición sin guardar los cambios.

  4. Escriba un código para realizar las siguientes funciones:

    • Controlar el evento EditCommand del control DataList, que establece la propiedad EditItemIndex del control DataList en el valor de índice del elemento que se va a situar en modo de edición. El índice del elemento en que hizo clic el usuario está disponible mediante la propiedad ItemIndex del objeto Item. Llamar a continuación al método DataBind del control.

    • Controlar el evento CancelCommand del control DataList, que establece la propiedad EditItemIndex del control DataList en -1, y llamar a continuación al método DataBind del control.

    • Controlar el evento UpdateCommand del control DataList. En el código, extraiga los valores de los controles del elemento actual y transfiéralos al control del origen de datos para llevar a cabo la operación de actualización. El código exacto que utilice depende del tipo de control de origen de datos con el que esté trabajando.

Ejemplo

En el ejemplo de código siguiente se muestra una página ASP.NET que utiliza un control DataList y un control SqlDataSource para mostrar la información de la tabla Categories en la base de datos Northwind. Los usuarios pueden editar los elementos.

<%@ Page Language="VB" %>

<script >
Protected Sub DataList1_EditCommand(ByVal source As Object, _
        ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs)
    DataList1.EditItemIndex = e.Item.ItemIndex
    DataList1.DataBind()
End Sub

Protected Sub DataList1_CancelCommand(ByVal source As Object, _
        ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs)
    DataList1.EditItemIndex = -1
    DataList1.DataBind()
End Sub

Protected Sub DataList1_UpdateCommand(ByVal source As Object, _
        ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs)
    Dim categoryID As String = _
        DataList1.DataKeys(e.Item.ItemIndex).ToString()
    Dim categoryName As TextBox = _
        CType(e.Item.FindControl("textCategoryName"), TextBox)
    Dim description As TextBox = _
        CType(e.Item.FindControl("textDescription"), TextBox)

    SqlDataSource1.UpdateParameters("original_CategoryID"). _
        DefaultValue = categoryID
    SqlDataSource1.UpdateParameters("categoryName"). _
        DefaultValue = categoryName.Text
    SqlDataSource1.UpdateParameters("Description"). _
        DefaultValue = description.Text
    SqlDataSource1.Update()
    DataList1.EditItemIndex = -1
    DataList1.DataBind()
End Sub
</script>

<html>
<head ></head>
<body>
  <form id="form1" >
    <div>
        <br />
        <asp:DataList  
            DataKeyField="CategoryID" 
            DataSourceID="SqlDataSource1" ID="DataList1"
            OnEditCommand="DataList1_EditCommand" 
            OnCancelCommand="DataList1_CancelCommand" 
            OnUpdateCommand="DataList1_UpdateCommand">
            <EditItemTemplate>
                ID: <asp:Label ID="Label1"  
                         Text='<%# Eval("CategoryID") %>'>
                    </asp:Label>
                <br />
                Name: <asp:TextBox ID="textCategoryName"  
                         Text='<%# Eval("CategoryName") %>'>
                      </asp:TextBox>
                <br />
                Description: <asp:TextBox ID="textDescription" 
                                  
                        Text='<%# Eval("Description") %>'>
                     </asp:TextBox>
                <br />
                <asp:LinkButton ID="LinkButton1"  
                    CommandName="update" >
                    Save
                </asp:LinkButton>
                &nbsp;
                <asp:LinkButton ID="LinkButton2" >
                    CommandName="cancel" 
                    Cancel
                </asp:LinkButton>
            </EditItemTemplate>
            <ItemTemplate>
                CategoryID:
                <asp:Label ID="CategoryIDLabel"  
                    Text='<%# Eval("CategoryID") %>'>
                </asp:Label>
                <br />
                CategoryName:
                <asp:Label ID="CategoryNameLabel" 
                     Text='<%# Eval("CategoryName") %>'>
                </asp:Label>
                <br />
                Description:
                <asp:Label ID="DescriptionLabel"  
                    Text='<%# Eval("Description") %>'>
                </asp:Label>
                <br />
                <asp:LinkButton  ID="LinkButton1" 
                    CommandName="edit" >
                    Edit
                </asp:LinkButton><br />
            </ItemTemplate>
        </asp:DataList>

        <asp:SqlDataSource ID="SqlDataSource1"  
              ConnectionString=
                  "<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT [CategoryID], [CategoryName], 
                 [Description] FROM [Categories]"
            UpdateCommand="UPDATE [Categories] SET [CategoryName] = 
                 @CategoryName, [Description] = @Description 
                 WHERE [CategoryID] = @original_CategoryID">
            <UpdateParameters>
              <asp:Parameter Name="CategoryName" Type="String" />
              <asp:Parameter Name="Description" Type="String" />
              <asp:Parameter Name="original_CategoryID" Type="Int32" />
            </UpdateParameters>
        </asp:SqlDataSource>
    </div>
  </form>
</body>
</html>
<%@ Page Language="C#" %>
<script >
protected void DataList1_EditCommand(object source, 
    DataListCommandEventArgs e)
{
    DataList1.EditItemIndex = e.Item.ItemIndex;
    DataList1.DataBind();
}

protected void DataList1_CancelCommand(object source, 
    DataListCommandEventArgs e)
{
    DataList1.EditItemIndex = -1;
    DataList1.DataBind();
}

protected void DataList1_UpdateCommand(object source, 
    DataListCommandEventArgs e)
{
    String categoryID = 
         DataList1.DataKeys[e.Item.ItemIndex].ToString();
    String categoryName = 
         ((TextBox)e.Item.FindControl("textCategoryName")).Text;
    String description = 
         ((TextBox) e.Item.FindControl("textDescription")).Text;

    SqlDataSource1.UpdateParameters["original_CategoryID"].DefaultValue 
        = categoryID;
    SqlDataSource1.UpdateParameters["categoryName"].DefaultValue 
        = categoryName;
    SqlDataSource1.UpdateParameters["Description"].DefaultValue 
        = description;
    SqlDataSource1.Update();

    DataList1.EditItemIndex = -1;
    DataList1.DataBind();
}
</script>
<html>
<head ></head>
<body>
  <form id="form1" >
    <div>
        <br />
        <asp:DataList  
            DataKeyField="CategoryID" 
            DataSourceID="SqlDataSource1" ID="DataList1"
            OnEditCommand="DataList1_EditCommand" 
            OnCancelCommand="DataList1_CancelCommand" 
            OnUpdateCommand="DataList1_UpdateCommand">
            <EditItemTemplate>
                ID: <asp:Label ID="Label1"  
                         Text='<%# Eval("CategoryID") %>'>
                    </asp:Label>
                <br />
                Name: <asp:TextBox ID="textCategoryName"  
                         Text='<%# Eval("CategoryName") %>'>
                      </asp:TextBox>
                <br />
                Description: <asp:TextBox ID="textDescription" 
                                  
                        Text='<%# Eval("Description") %>'>
                     </asp:TextBox>
                <br />
                <asp:LinkButton ID="LinkButton1"  
                    CommandName="update" >
                    Save
                </asp:LinkButton>
                &nbsp;
                <asp:LinkButton ID="LinkButton2" >
                    CommandName="cancel" 
                    Cancel
                </asp:LinkButton>
            </EditItemTemplate>
            <ItemTemplate>
                CategoryID:
                <asp:Label ID="CategoryIDLabel"  
                    Text='<%# Eval("CategoryID") %>'>
                </asp:Label>
                <br />
                CategoryName:
                <asp:Label ID="CategoryNameLabel" 
                     Text='<%# Eval("CategoryName") %>'>
                </asp:Label>
                <br />
                Description:
                <asp:Label ID="DescriptionLabel"  
                    Text='<%# Eval("Description") %>'>
                </asp:Label>
                <br />
                <asp:LinkButton  ID="LinkButton1" 
                    CommandName="edit" >
                    Edit
                </asp:LinkButton><br />
            </ItemTemplate>
        </asp:DataList>

        <asp:SqlDataSource ID="SqlDataSource1"  
              ConnectionString=
                 "<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT [CategoryID], [CategoryName], 
                 [Description] FROM [Categories]"
            UpdateCommand="UPDATE [Categories] SET [CategoryName] = 
                 @CategoryName, [Description] = @Description 
                 WHERE [CategoryID] = @original_CategoryID">
            <UpdateParameters>
               <asp:Parameter Name="CategoryName" Type="String" />
              <asp:Parameter Name="Description" Type="String" />
              <asp:Parameter Name="original_CategoryID" Type="Int32" />
            </UpdateParameters>
        </asp:SqlDataSource>
    </div>
  </form>
</body>
</html>

Para actualizar los datos, necesita la clave principal del registro que se está actualizando. Puede obtener este valor de la propiedad DataKeyField, que contiene una matriz de claves.

Para obtener el valor de un control específico del elemento, utilice el método FindControl del objeto argumento del evento Item.

Los valores que establece en el diccionario SqlDataSource1.UpdateParameters deben coincidir con los nombres que ha especificado en el elemento UpdateParameters.

Compilar el código

El código necesita que tenga una cadena de conexión denominada NorthwindConnectionString. Se supone que la base de datos a la que se conecta tiene una tabla denominada Categories con los campos CategoryID, CategoryName y Description.

La cuenta bajo la que se conecta la página a la base de datos debe tener permiso para actualizar la tabla Category.

Programación eficaz

En el código del ejemplo no se realizan las siguientes tareas que normalmente se llevarían a cabo en un entorno de producción:

  • El código no incluye la comprobación de errores para garantizar que el método FindControl devuelve un control válido. Para que el código sea más sólido, asegúrese de que el valor devuelto por el método FindControl no es una referencia nula (Nothing en Visual Basic).

  • El código no comprueba si la actualización se ha realizado correctamente.

Seguridad

Los datos proporcionados por el usuario en una página de formularios Web Forms pueden contener secuencias de comandos del cliente malintencionadas. De forma predeterminada, la página de formularios Web Forms valida los datos escritos por el usuario para comprobar que no incluyen secuencias de comandos ni elementos HTML. Para obtener más información, vea Información general sobre los ataques mediante secuencias de comandos.

Vea también

Conceptos

Modificar datos mediante el control SqlDataSource

Utilizar parámetros con el control SqlDataSource

Referencia

Información general sobre DataList (Control de servidor Web)