Pregunta

No puedo obtener mi GridView para permitir que un usuario ordene una columna de datos cuando estoy usando un SqlDataSource personalizado.

Tengo un GridView en el que el código en la referencia de ASP en el HTML es mínimo:

<asp:GridView id="grid" runat="server" AutoGenerateColumns="False" AllowSorting="True">
</asp:GridView>

En el código subyacente adjunto un SqlDataSource creado dinámicamente (las columnas que contiene no siempre son las mismas, por lo que el SQL utilizado para crearlo se construye en tiempo de ejecución). Por ejemplo:

Configuré las columnas ...

BoundField column = new BoundField();
column.DataField = columnName;
column.HeaderText = "Heading";
column.SortExpression = columnName;

grid.Columns.Add(column);

la fuente de datos ...

SqlDataSource dataSource = new SqlDataSource(
    "System.Data.SqlClient",
    connectionString, 
    generatedSelectCommand);

luego la vista de cuadrícula ...

grid.DataSource = dataSource;
grid.DataKeyNames = mylistOfKeys;
grid.DataBind();

En este momento no ocurre nada cuando un usuario hace clic en el encabezado de una columna cuando espera que ordene los datos de la columna. ¿Alguien tiene alguna idea de lo que me estoy perdiendo?

¡Si hay una forma más agradable de hacer esto, eso también sería útil ya que me parece complicado!

¿Fue útil?

Solución

Primero necesitas agregar un evento:

<asp:GridView AllowSorting="True" OnSorting="gvName_Sorting" ...

Entonces ese evento parece:

protected void gvName_Sorting( object sender, GridViewSortEventArgs e )
{
    ...
    //rebind gridview
}

Básicamente, debes volver a obtener tus datos.

Tienes razón en que se ve desordenado y hay una mejor manera: ASP.Net MVC

Lamentablemente, ese es un modelo de página drásticamente diferente.

Otros consejos

También puede simplemente reasignar el origen de datos. Seleccione el comando antes de la llamada DataBind () en el controlador de clasificación. Algo como esto:

protected void gvItems_Sorting(object sender, GridViewSortEventArgs e)
{
    GridView gv = (GridView)sender;
    SqlDataSource ds = (SqlDataSource)gv.DataSource;
    ds.SelectCommand = ds.SelectCommand + " order by " 
        + e.SortExpression + " " + GetSortDirection(e.SortDirection);
    gvItems.DataSource = ds;
    gvItems.DataBind();
}

string GetSortDirection(string sSortDirCmd)
{
    string sSortDir;
    if ((SortDirection.Ascending == sSortDirCmd))
    {
        sSortDir = "asc";
    }
    else
    {
        sSortDir = "desc";
    }
    return sSortDir;
}

Espero que esta ayuda. Avíseme si necesita ayuda adicional para implementarlo.

¡Disfruta!

No estoy seguro de esto, pero si usas un SqlDataSource estándar y haces clic en un campo para clasificar de acuerdo con ese campo, SqlDataSource se rellena nuevamente con los datos y vuelve a la cuadrícula. Por lo tanto, la clasificación no se realiza en el lado del cliente y también se puede hacer solo cuando el método select de SQLDataSource no es DataReader.

Al manejar el evento de clasificación, ¿recrean el SqlDataSource y lo rebotan en el GridView? ¿Puede colocar el campo y la dirección de ordenación en el GenererSelectCommand, que utiliza? ¿O ponerlo en la propiedad SortParameterName de SQLDataSource?

Estoy absolutamente seguro de que tienes que hacer que SqlDataSource se recupere de la cuadrícula y, como lo creas sobre la marcha, debes poblarlo nuevamente.

¿Mejor tarde que nunca?

Alguna adición a la sugerencia de Keith que es básicamente la correcta.

La verdad es que tienes que lidiar con la clasificación en el evento gridView_Sorting. No hay necesidad de DataBind () el GridView anterior, por ejemplo en el evento Page_Load. Allí solo debe llamar al método GridView.Sort () en lugar de .DataBind (). Aquí está cómo va:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then

        Me.gridView.Sort(Request.QueryString("sortExpression"), Request.QueryString("sortDirection"))

    End If

End Sub

A continuación, veamos el evento gridView_Sorting.

Allí tienes que empujar la fuente de datos a la clasificación correcta. GridView en sí no lo maneja (al menos en este caso).

Protected Sub gridView_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles gridView.Sorting
    If IsPostBack Then
        e.Cancel = True
        Dim sortDir As SortDirection = SortDirection.Ascending
        If e.SortExpression = Me.Q_SortExpression And Me.Q_SortDirection = SortDirection.Ascending Then
            sortDir = SortDirection.Descending
        End If
        RedirectMe(e.SortExpression, sortDir)
    Else
        Dim sortExpr As String = e.SortExpression + " " + IIf(e.SortDirection = SortDirection.Ascending, "ASC", "DESC")
        Dim dv As System.Data.DataView = Me.dsrcView.Select(New DataSourceSelectArguments(sortExpr))
        Me.gridView.DataSource = dv
        Me.gridView.DataBind()
    End If
End Sub

No es necesario codificar ninguna funcionalidad de clasificación en el origen de datos, como pasar los parámetros de clasificación al procedimiento almacenado. Toda la clasificación tiene lugar en las piezas de código anteriores.

Además, es bueno tener el gridView.EnableViewState cambiado a False, lo que hace que la página sea mucho más ligera para el tráfico de red y también para el navegador. Puede hacerlo ya que la cuadrícula se recrea completamente cuando la página vuelve a publicarse.

¡Que tengas un buen día!

Martin

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top