Encuentra un registro especí­fico dentro de un DataList

Tengo un DataList como este:

  1. <asp:DataList ID="DataList1" runat="server" DataSourceID="ObjectDataSource1" DataKeyField="idarticulo">
  2. <ItemTemplate>
  3.     <table>
  4.         <tr>
  5.             <td>
  6.                 <%# Eval("titulo") %>
  7.             </td>
  8.         </tr>
  9.         <tr>
  10.             <td>
  11.                 <asp:LinkButton ID="LinkButton1" runat="server" CommandName="Download" CommandArgument="1"><%#Eval("aa1titulo")%></asp:LinkButton>
  12.                 <asp:LinkButton ID="LinkButton2" runat="server" CommandName="Download" CommandArgument="2"><%#Eval("aa2titulo")%></asp:LinkButton>
  13.             </td>
  14.         </tr>                      
  15.     </table>    
  16. </ItemTemplate>
  17. </asp:DataList>

Nota:
aa1titulo y aa2titulo son títulos que guardo para mis archivos adjuntos 1 y 2.

La idea es que esos LinkButtons, al ser presionados, deben servir para que el usuario descargue unos archivos. En este ejemplo manejo dos archivos adjuntos para cada registro, por eso tengo dos LinkButtons.

Cuando se oprima alguno de esos LinkButtons, tengo que saber si se oprimió el primero o el segundo, para saber cuál de los dos archivos adjuntos enviar. También tengo que saber a cuál registro pertenece el LinkButton oprimido, para poder escoger el archivo adecuado.

Fíjate que a todos los LinkButtons les puse el CommandName establecido a Download. De esa manera voy a identificar que lo que se quiere hacer es una descarga. Ahora bien, a cada uno de ellos le establecí la propiedad CommandArgument a una distinta: 1 para el primer archivo adjunto y 2 para el segundo.

Con esto sabré si quieren descargar el primer archivo adjunto o el segundo. Ahora bien, suponiendo que en el DataList aparecerán n registros, ¿cómo voy a saber a cuál de los registros le hicieron clic en alguno de sus LinkButtons?

Nota que al DataList le he establecido la propiedad DataKeyField a idarticulo. Lo hice así porque la llave principal de mi tabla se llama idarticulo. Con esa llave encontraremos el registro al cual se le hizo clic.

Ok, ahora debes saber que el DataList tiene un evento que se llama ItemCommand, que se ejecuta precisamente cuando hagan clic en alguno de los LinkButtons. ¿Por qué? Porque les asigné la propiedad CommandName.

Entonces toda la operación la tenemos que hacer precisamente en ese evento, así:

  1. Protected Sub DataList1_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) Handles DataList1.ItemCommand
  2.         If e.CommandName = "Download" Then
  3.             EmpujaArchivo(Me, DataList1.DataKeys(CType(e.Item.ItemIndex, Integer)), e.CommandArgument)
  4.         End If
  5. End Sub

Nota:
La función EmpujaArchivo simplemente envía el archivo utilizando Page.Response.WriteFile. El primer parámetro es la página como tal (por eso le estamos pasando Me), el segundo parámetro es el artículo en el cual se encuentra el archivo adjunto solicitado, y el tercer parámetro es cuál de los archivos adjuntos (1 ó 2) se debe enviar.

Cómo borrar un archivo en asp.net 2

Antes que nada, recuerda importar System.IO:

  1. Imports System.IO

Para eliminar el archivo haz lo siguiente:

  1. Protected Sub aa1Borrar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles aa1Borrar.Click
  2.    Try
  3.       Dim RutaArch As String
  4.       RutaArch = MapPath(".") & "archivo.doc"
  5.       Dim Archivo As FileInfo = New FileInfo(RutaArch)
  6.       If Archivo.Exists Then
  7.           File.Delete(RutaArch)
  8.       Else
  9.           Throw New FileNotFoundException()
  10.       End If
  11.  
  12.    Catch excepcion As FileNotFoundException
  13.       aa1Mensaje.Text += excepcion.Message
  14.  
  15.    Catch excepcion As Exception
  16.       aa1Mensaje.Text += excepcion.Message
  17.  
  18.    End Try
  19.  
  20.  End Sub

Usando FindControl cuando tienes una MasterPage

Si estás tratando de usar FindControl para encontrar un control que está en una página que está basada en una MasterPage, utiliza la siguiente notación para encontrarlo:

Page.Master.FindControl("NombreDeLaForma").FindControl("NombreDelContentPlaceHolder").FindControl("ControlQueBuscas")

Ejemplo, supón que tu MasterPage es:

  1. <%@ Master Language="VB" CodeFile="Ppal.master.vb" Inherits="Ppal" %>
  2.  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4.  
  5. <html xmlns="http://www.w3.org/1999/xhtml" >
  6. <head runat="server">
  7.     <title>Titulo</title>
  8. </head>
  9. <body>
  10.     <form id="form1" runat="server">
  11.         <asp:contentplaceholder id="Cuerpo" runat="server">
  12.         </asp:contentplaceholder>
  13.     </form>
  14. </body>
  15. </html>

También supón que tienes una página basada en ese MasterPage, cuyo código es:

  1. <%@ Page Language="VB" MasterPageFile="~/Ppal.master" AutoEventWireup="false" CodeFile="Ejemplo.aspx.vb" Inherits="Ejemplo" title="Untitled Page" %>
  2. <asp:Content ID="Content1" ContentPlaceHolderID="Cuerpo" Runat="Server">
  3.     <asp:TextBox ID="CajaTexto" runat="server"></asp:TextBox>
  4. </asp:Content>

El código que usarías para encontrar CajaTexto y modificar alguna de sus propiedades sería este:

  1. Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  2.         Dim Caja As TextBox
  3.         Caja = Page.Master.FindControl("form1").FindControl("Cuerpo").FindControl("CajaTexto")
  4.         Caja.Text = "Hola"
  5.     End Sub

Validadores para controles CheckBox y CheckBoxList (ASP.NET 2)

Me parece raro que ASP.NET no venga con validadores para los controles CheckBox y CheckBoxList.

De cualquier forma, Scott Mitchell escribió unos validadores que funcionan muy bien, de hecho funcionan sin necesidad de hacer PostBack.

Es cuestión de descargar los DLLs, ponerlos en tu fólder bin, registrar el Assembly en tu página y utilizarlos.

Toda la explicación junto con los archivos los puedes descargar de este post de 4GuysFromRolla.

OJO:
No funcionan dentro de un UpdatePanel de Ajax.

Los controles de validación no funcionan dentro de un UpdatePanel

Estoy trabajando con:
ASP.NET 2.0.50727
Extensiones Ajax 1.0

Puse un UpdatePanel que contiene campos que el usuario va a llenar. Puse controles de validación para asegurarme de que el usuario llena los campos. Los controles de validación funcionaban de una manera extraña, y además aparecía este error:

Invalid postback or callback argument. Event validation is enabled using in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

Estuve investigando y resulta ser que los controles de validación no funcionan dentro de un UpdatePanel. Encontrarás más información aquí:
http://forums.asp.net/t/1116324.aspx (lee el segundo post).

Lo bueno es que hay una manera de darle la vuelta a este problema.

La razón del problema y la solución se encuentra aquí:
http://blogs.msdn.com/mattgi/archive/2007/01/23/asp-net-ajax-validators.aspx

Pero te la traduzco. 🙂

Tienes que bajarte estos archivos y ponerlos en el fólder bin de tu aplicación.

Después de eso, abre tu archivo web.config y dentro de la sección Pages teclea lo siguiente:

<tagmapping>

<add tagtype="System.Web.UI.WebControls.CompareValidator" mappedtagtype="Sample.Web.UI.Compatibility.CompareValidator, Validators, Version=1.0.0.0"></add> 

<add tagtype="System.Web.UI.WebControls.CustomValidator" mappedtagtype="Sample.Web.UI.Compatibility.CustomValidator, Validators, Version=1.0.0.0"></add> 

<add tagtype="System.Web.UI.WebControls.RangeValidator" mappedtagtype="Sample.Web.UI.Compatibility.RangeValidator, Validators, Version=1.0.0.0"></add> 

<add tagtype="System.Web.UI.WebControls.RegularExpressionValidator" mappedtagtype="Sample.Web.UI.Compatibility.RegularExpressionValidator, Validators, Version=1.0.0.0"></add> 

<add tagtype="System.Web.UI.WebControls.RequiredFieldValidator" mappedtagtype="Sample.Web.UI.Compatibility.RequiredFieldValidator, Validators, Version=1.0.0.0"></add> 

<add tagtype="System.Web.UI.WebControls.ValidationSummary" mappedtagtype="Sample.Web.UI.Compatibility.ValidationSummary, Validators, Version=1.0.0.0"></add>

</tagmapping>

Yo lo probé y funciona ¡perfectamente!

Más adelante Microsoft sacará un parche para no tener que hacer este truco, así que si se te presenta este problema, te recomiendo primero bajarte la versión más nueva de ASP.NET y de las Extensiones de Ajax.