Mostrando entradas con la etiqueta gridview. Mostrar todas las entradas
Mostrando entradas con la etiqueta gridview. Mostrar todas las entradas

miércoles, 17 de septiembre de 2008

ASP.NET. Conservar SelectCommand de SqlDatasource entre postbacks

Todos hemos flipado la primera vez que en dos patadas hemos enganchado un SqlDataSource a un GridView y automáticamente hemos obtenido contenido de la b.d. en nuestro grid, siendo capaces de paginarlo, ordenarlo... todo funciona de maravilla con el SelectCommand del SqlDataSource que hemos establecido en tiempo de diseño.

El siguiente paso es modificar ese SelectCommand en función de los criterios aportados por el usuario. Ponemos el típico botón buscar y en su evento "click" construimos nuestro SelectCommand. La primera página del grid se carga correctamente, pero si intentamos paginar ya la cosa se fastidia...

Esto es debido a que, por razones obvias de seguridad, el control SqlDataSource no guarda por defecto ninguno de sus comandos (select, update, etc...) en el ViewState. Como consecuencia, su contenido no se conserva entre postbacks, y es necesario almacenarlo de alguna manera y asignarlo en cada load si queremos que perdure.

Una manera de hacerlo es usar el propio viewstate, pero teniendo la precaución indispensable de encriptarlo. Para ello añadimos en la directiva page de nuestro aspx:

ViewStateEncryptionMode="Always"


En el click del botón construimos el selectCommand y lo almacenamos en el viewstate:

Protected Sub btBuscar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
ViewState("selectGrid") = "select * from tabla"
SqlDataSource1.SelectCommand = ViewState("selectGrid")
End Sub


Para recuperarlo en el load de la página:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not ViewState("selectGrid") Is Nothing Then
SqlDataSource1.SelectCommand = ViewState("selectGrid")
End If
End Sub

jueves, 7 de febrero de 2008

Campo de GridView con enlace a valor del campo. 2ªparte (imagen con enlace)

Si queremos tener una imagen con enlace en una columna de un gridview y que el enlace dependa de un dato de nuestra base de datos, tenemos que añadir una columna TemplateField al gridview. Este TemplateField deberá contener un objeto HyperLink en el que definimos el enlace mediante una cadena de formato y en el que referenciamos el campo de la tabla (mediante {0}).

En la vista código veríamos algo parecido a lo siguiente :

<Columns>

...

<asp:TemplateField HeaderText="ImagenConEnlace">

<ItemTemplate>

<asp:HyperLink ID="HL_ImagenConEnlace" runat="server"

ImageUrl="~/carpeta1/imagenMostradaEnGridview.gif"

Text='texto_mostrado_cuando_el_raton_esta_sobre_la_imagen'

Target="_blank"

NavigateUrl='<%# Eval("nombre_campo_tabla", "~/carpeta2/{0}") %>'>

</asp:HyperLink>

</ItemTemplate>

</asp:TemplateField>

...

</Columns>


(Análogamente, podemos hacer que la imágen mostrada dependa de un campo de la tabla empleando también una cadena de formato)

jueves, 13 de diciembre de 2007

Gridview: recuperar el índice de la fila desde un template field

Caso práctico: para cada fila de un GridView quieres poner un enlace/botón que realice cierta operación (llamémosle "pitufar") con el registro de esa fila. Sin problemas: editas las columnas del GridView y le metes un ButtonField con:

text="Pitufar"
CommandName="Pitufar"

Luego en el evento RowCommand del GridView te marcas un bonito:
If e.CommandName = "Pitufar" Then
  GridView1.SelectedIndex = Convert.ToInt32(e.CommandArgument)
  pitufeame(GridView1.SelectedValue)
  GridView1.DataBind()
End If

Y ya lo tienes.

Pero... ¿Y si necesitas convertir ese ButtonField a TemplateField? Mala cosa, porque entonces el código del RowCommand dejará de funcionar por la sencilla razón de que en e.CommandArgument ya no tendrás el índice de la fila que han clickeado.

Solución: En la propiedad CommandArgument del TemplateField hay que poner:



Y todo vuelve a funcionar.

miércoles, 12 de diciembre de 2007

Campo de GridView con enlace a valor del campo

Lo que se pretende es poder tener un GridView pero que uno de los campos se comporte como un enlace, con la peculiaridad de que el valor que se mostrará será de un campo, y el valor al que enlazará será de otro.

Esto que en ASP 3.0 parecía sencillo en ASP.NET no es complejo, sólo es necesario conocer las propiedades que se han de tocar para esta acción. Aunque a mí me he llevado mi tiempo.

Primeramente se deberá disponer de un sqlDataSource u otro origen de datos similar y que esté correctamente configurado.

A continuación agregaremos un GridView y lo enlazaremos con el control sqlDataSource a través de la propiedad DataSourceId o usando la etiqueta inteligente del control GridView.

Una vez lo tengamos, deben de aparecer los campos en el GridView, y es momento de acceder a "Editar columnas ..." a través de la etiqueta inteligente del control GridView.

En la caja campos disponibles, agregaremos uno denominado "Campo HyperLink", y los valores que tocaremos serán:

-DataNavigateUrlFields: Será el campo que contiene el valor con el que pretendemos enlazar.
-DataTextField: Será el campo que contiene el valor que deseamos sea visto en el GridView.
-DataNavigateUrlFormatString: Será la que contenga el formato de cómo deberá se referenciará al campo contenido en DataNavigateUrlFields. Sería el caso de establecer la ruta relativa, o componer una dirección. Ejemplo: ../../Repositorio/{0}
{0}, sustituirá al valor del campo por cada registro de DataNavigateUrlFields.

Otros valores opcionales:
-SortExpresion: Se establecerá el campo por el que se ordenará la columna.
-Target: El modo en que se abrirá la ventana, en la misma ventana, una nueva, etc.

Nada más.

miércoles, 24 de octubre de 2007

Diversos ejemplos del uso del parámetro "e" en eventos de actualización

En el evento ItemInserted de un FormView, para acceder al valor de un campo del registro recién insertado:

e.Values.Item("NombreCampo").ToString()


En el evento RowUpdating de un GridView, o en el ItemUpdating de un FormView, para hacer comprobaciones de validez de datos:

'no permitir dejar vacío el primer campo
If e.NewValues().Item(0) Is Nothing Then
   darAviso("No puede dejar vacío el campo X")
   e.Cancel = True
   Exit Sub
End If
'obligar a que el nuevo valor sea diferente al viejo
If (e.NewValues().Item(0).ToString = e.OldValues().Item(0).ToString) Then
   darAviso("Debe cambiar el valor del campo X")
   e.Cancel = True
   Exit Sub
End If


También a través de "e" se puede acceder a la colección Keys definida en el control para establecer los campos que conforman la clave de nuestro conjunto de datos. Por ejemplo en un RowDeleting de un GridView podemos hacer comprobaciones de integridad antes de cargarnos la fila:

If hayRegistrosDependientes(e.Keys.Item("Id").ToString()) Then
   e.Cancel = True
   darAviso("Imposible borrar. Dejas la BD hecha un solar")
End If


Los ejemplos son un poco simples, pero que cada uno los complique tanto como quiera, o como necesite.

Hale!

miércoles, 17 de octubre de 2007

Establecer color dependiendo de una condición en un GridView

Habitualmente mostramos los datos en un gridview más o menos "tuneados" que dirían, usando las propiedades de dicho control.

Hasta aquí todo bien. El problema, cuando en función a un determinado valor se debía cambiar cierta propiedad.

En el caso que me ocupaba, si obtenía del registro de la tabla o vista que mostraba en el gridview, una E, debía escribir una E y establecer la propiedad BackColor de tal modo que fuese Amarillo. Y si obtenía una P, pues escribiría el valor P y el color Rojo.

Para ello:

/1/ "Editar Columnas" de las opciones de la etiqueta inteligente del GridView.
/2/ Seleccionar el campo sobre el que deseamos proceder y convertirlo en template, para ello nos posicionamos y "Convertir este informe en TemplateField". Y Aceptar.
/3/ "Editar Plantillas" de las opciones de la etiqueta inteligente del GridView. Debemos estar en la plantilla ItemTemplate.
/4/ Seleccionar el Label de la plantilla, y "Editar DataBinding ..." de las opciones de la etiqueta inteligente del Labek.
/5/ En la propiedad Text, establecer "Con enlace a" y seleccionamos nuestro campo, es este caso el mío era Estado.
/6/ Activamos "Mostrar todas las propiedades"
/7/ Nos desplazamos a la propiedad BackColor.
/8/ Activamos "Personalizar enlace", y escribimos:

IIf(Eval("Estado")="E",System.Drawing.Color.Yellow,
    System.Drawing.Color.Red)


O dicho de otro modo, si el valor del campo de Estado es E entonces, fondo amarillo y si no fondo rojo.

También se puede establecer el color en modo hexadecimal, debiendo sustituir lo que proceda por:

System.Drawing.Color.FromName("#FFFF80")


Al final, el entorno Visual Studio genera esta línea por si puede ser más claro todo (click para ampliar):



Nada más.