El Blog de Óscar Sotorrío Sánchez - MCP Application Development Foundation - C#

Todo lo que vaya aprendiendo de .NET, C#, ASP.NET, SQL Server, etc, lo compartiré con vosotros.

El autor:

Óscar Sotorrío Sánchez
Contacto Send mail

Encuéntralo

Álguien dijo...


El deseo de ganar es importante, pero el deseo de prepararse es vital.

Joe Paterno

GridView: asignar dinámicamente el texto de CommandField

En ocasiones debemos mostrar informes en controles GridView en los que una, o varias, de sus columnas nos permitan seleccionar una fila para realizar una determinada acción en nuestro código. De forma predeterminada el control GridView nos permite añadir columnas de tipo BoundFile, ButtonField, CheckBoxField, CommandField, HyperLinkField, etc.

El problema con estas columnas es que el texto mostrado por pantalla siempre es el mismo en cada fila del GridView. Por ejemplo, "Seleccionar" para una columna CommnadField de tipo ShowSelectButton.

Pero esto no es lo que queremos conseguir. Se trata de que cada fila en una columna determinada por nosotros muestre el texto de los datos de la fuente de datos.

De esta forma cada registro permite seleccionar esa fila para realizar una acción en función de los datos que contiene. ¡Veamos como!. 

Tenemos el siguiente GridView en nuestro formulario:

         <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 

            ondatabound="GridView1_DataBound" 
            onselectedindexchanged
="GridView1_SelectedIndexChanged">
            
<Columns>
                
<asp:CommandField ShowSelectButton="true" ButtonType="Link" HeaderText="Proyecto" />
                <
asp:BoundField DataField="Responsable" HeaderText="Responsable" ReadOnly="True" 
                    SortExpression
="Responsable" />
                <
asp:BoundField DataField="Analista" HeaderText="Analista" 
                    SortExpression
="Analista" />
                <
asp:BoundField DataField="FechaInicio" HeaderText="Fecha Inicio" 
                    SortExpression
="FechaInicio" />
                <
asp:BoundField DataField="FechaFin" HeaderText="Fecha Fin" 
                    SortExpression
="FechaFin" />
            </
Columns>
        
</asp:GridView>


Ahora cargamos el GridView con un DataTable por ejemplo en el evento load.

    protected void Page_Load(object sender, EventArgs e)
    {
        
if (!IsPostBack)
        {
            dt 
= new DataTable();
            
dt.Columns.Add("Proyecto");
            
dt.Columns.Add("Responsable");
            
dt.Columns.Add("Analista");
            
dt.Columns.Add("FechaInicio");
            
dt.Columns.Add("FechaFin");

            int 
contador 0;
            foreach 
(DataColumn colum in dt.Columns)
            {
                DataRow dr 
dt.NewRow();
                
dr["Proyecto""000" + contador.ToString();
                
dr["Responsable""Responsable " + contador.ToString();
                
dr["Analista""Analista " + contador.ToString();
                
dr["FechaInicio""Inicio " + contador.ToString();
                
dr["FechaFin""Fin " + contador.ToString();
                
dt.Rows.Add(dr);
                
contador++;
            
}

            GridView1.DataSource 
dt;
            
GridView1.DataBind();
        
}
    }

En el evento OnDataBound asignamos dinámicamente los datos de la columna CommnadField.

    protected void GridView1_DataBound(object sender, EventArgs e)
    {
        
for (int 0i < dt.Rows.Counti++)
        {
            LinkButton lb 
GridView1.Rows[i].Controls[0].Controls[0as LinkButton;
            
lb.Text dt.Rows[i]["Proyecto"].ToString();
        
}
    }

En este caso la fuente de datos era un DataTable que hemos creado a mano pero podíamos haber utilizado cualquier origen de datos. Por ejemplo, si hubiéramos utilizado un objeto SqlDataSource podríamos recuperar los datos de la forma siguiente.

        DataView dv =  SqlDataSource1.Select(new DataSourceSelectArguments()) as DataView;
        
DataTable dt dv.ToTable();

 

Ahora solo nos queda recoger los datos sobre la celda que pulsa el usuario. Utilizaremos para ello el evento OnSelectedIndexChanged.

    protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
    {
        GridView gv 
(GridView)sender;
        int 
filaSeleccionada gv.SelectedIndex;
        
LinkButton lb gv.Rows[filaSeleccionada].Cells[0].Controls[0as LinkButton;
    
}

Posted by Oscar.SS on domingo, 14 de marzo de 2010 14:09
Permalink | Comentarios (0) | Post RSSRSS comment feed

GridView: acceder a los valores de las columnas no visibles

Cuando intentamos acceder al valor de una celda, de una columna marcada en el GridView como no visible, nos encotramos ante un problema. Dado que, normalmente las columnas marchadas como no visibles, suelen almacenar datos nada importantes para el usuario (id, codigos, valores ocultos, etc) pero si de suma importancia para el funcionamiento interno de nuestra aplicación.

Por lo tanto, lógicamente el siguiente intento no nos devolverá nada porque la columna no visible no ha sido "pintada".

string id gvEmpleados.Rows[e.RowIndex].Cells[celdaId].Text;

Para resolver este pequeño problema debemos utilizar las propiedades DataKayNames y Datakeys del GridView. Veamos un ejemplo.

Tenemos el siguiente XML que deseamos mostrar por pantalla al usuario por medio de una rejilla como GridView.

<?xml version="1.0" encoding="utf-8"?>
<empleados>
    
<empleado id="1" idEmpresa="034/9435" Nombre="Pedro" Telefono="985945452" Pais="Mexico" />
    <
empleado id="2" idEmpresa="035/3245" Nombre="Antonio" Telefono="887404730" Pais="Perú" />
    <
empleado id="3" idEmpresa="078/4324" Nombre="Jorge" Telefono="9149858353" Pais="España" />
    <
empleado id="4" idEmpresa="045/3243" Nombre="Elena" Telefono="893737581" Pais="Argentina" />
    <
empleado id="5" idEmpresa="074/5425" Nombre="Raquel" Telefono="9984573423" Pais="España" />
</
empleados> 

Nuestro GridView tendrá la siguiente definición de código HTML en nuestra página.

 

<asp:GridView ID="gvEmpleados" runat="server" AutoGenerateColumns="False" 
            DataSourceID
="XmlDataSourceEmpleados" DataKeyNames="id,idEmpresa" 
            onrowdeleting
="gvEmpleados_RowDeleting" 
            onselectedindexchanging
="gvEmpleados_SelectedIndexChanging">
            
<Columns>
                
<asp:CommandField ShowSelectButton="True" />
                <
asp:BoundField DataField="id" HeaderText="id" SortExpression="id" 
                    Visible
="False" />
                <
asp:BoundField DataField="idEmpresa" HeaderText="idEmpresa" 
                    SortExpression
="idEmpresa" Visible="False" />
                <
asp:BoundField DataField="Nombre" HeaderText="Nombre" 
                    SortExpression
="Nombre" />
                <
asp:BoundField DataField="Telefono" HeaderText="Telefono" 
                    SortExpression
="Telefono" />
                <
asp:BoundField DataField="Pais" HeaderText="Pais" SortExpression="Pais" />
                <
asp:CommandField ShowDeleteButton="True" />
            </
Columns>
        
</asp:GridView>
        
<asp:XmlDataSource ID="XmlDataSourceEmpleados" runat="server" 
            DataFile
="~/App_Data/empleados.xml"></asp:XmlDataSource>
He marcado en negrita y un poco más grande las columnas no visibles al usuario. También podemos ver la propiedad DataKeyNames. Esta propiedad permite establecer (también recuperar) una colección de columnas que serán tratadas como claves primarias del origen de datos.
 
Ahora solo nos queda desde código acceder a estos valores cuando el usuario dispare cualquiera de los eventos del GridView. Ya sea para actualizar, eliminar, seleccionar, etc una fila. Un par de ejemplos:
 
 
    protected void gvEmpleados_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
    {
        var colsNoVisible 
gvEmpleados.DataKeys[e.NewSelectedIndex].Values;
        string 
id (string)colsNoVisible[0];
        string 
idEmpresa (string)colsNoVisible[1];
    
}
    
protected void gvEmpleados_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        var colsNoVisible 
gvEmpleados.DataKeys[e.RowIndex].Values;
        string 
id (string) colsNoVisible[0];
        string 
idEmpresa (string) colsNoVisible[1];
    
}

La propiedad DataKeys nos permite acceder a las columnas que son tratadas como claves primarias en el origen de datos. De esta forma nosotros podemos trabajar por debajo con registros únicos como ids y mostrar al usuario solo la información que le interesa.

 


Posted by Oscar.SS on domingo, 06 de diciembre de 2009 15:26
Permalink | Comentarios (0) | Post RSSRSS comment feed

DataGridView: posicionar scroll

Esta es una cuestión muy simple y sencilla pero me ha parecido correcto incluirla en un post porque es de ese tipo de cosas que siempre se preguntan y nadie escribe sobre ello porque parece demasiado trivial.

Supongamos el caso de un DataGridView que contiene multitud de líneas y el usuario se desplaza por el mismo con un scroll vertical. En un momento dado el usuario cambia el contenido de una celda y actualiza para que los cambios sean volcados en la base de datos que alimenta el DataGridView.

¿Qué ocurre?. Que al actualizar el scroll sube a la parte de arriba, perdiendo de vista en la pantalla el cambio efectuado.

La solución es la siguiente:

            int indiceFilaSelec dataGridView1.CurrentRow.Index;
            
dataGridView1.FirstDisplayedScrollingRowIndex indiceFilaSelec;

También se puede obtener el índice de la fila seleccionada con dataGridView1.SelectedRows[0].Index;


Posted by Oscar.SS on jueves, 02 de julio de 2009 8:51
Permalink | Comentarios (0) | Post RSSRSS comment feed