Tengo un ASPxGridView que contiene una columna con un DataItemTemplate que contiene un ASPxCheckBox. Luego tengo un botón fuera de la cuadrícula que realiza algunas acciones en función de si la casilla de verificación está marcada.

La cuadrícula se define como:

<dx:ASPxGridView ID="grid" runat="server">
    <Columns>
        <dx:GridViewDataColumn>
            <DataItemTemplate>
                <ds:ASPxCheckBox ID="checkbox" runat="server" />
            </DataItemTemplate>
        </dx:GridViewDataColumn>
    <Columns>
</dx:ASPxGridView>

La cuadrícula se completa en Page_Load como tal:

protected void Page_Load(object sender, EventArgs e)
{
    //Some stuff
    grid.DataSource = sourceTable;
    grid.DataBind();
    //Other stuff
}

Donde sourceTable se define como:

public DataTable sourceTable
{
    get
    {
        if (ViewState["sourceTable"] == null)
            return new DataTable();
        return (DataTable)ViewState["sourceTable"];
    }
    set
    {
        ViewState["sourceTable"] = value;
    }
}

Y poblado en otro lugar. (La población no es importante y funciona)

El código se implementa como tal para garantizar que la clasificación y la paginación funcionen correctamente en la cuadrícula, como se define en varios temas de soporte de DevExpress. Esto es entendible. Sin embargo, cuando intentamos obtener el valor de Checked de checkbox al hacer clic en el botón, siempre es falso:

protected void button_Click(object sender, EventArgs e)
{
    //Some stuff
    for(int i = 0; i < grid.VisibleRowCount; i++)
    {
        //Other stuff
        ASPxCheckBox checkbox = grid.FindRowCellTemplateControl(i, grid.Columns[0], "checkbox") as ASPxCheckBox;
        if(checkbox.Checked) //Always false
        {
            //Do conditional stuff
        }
        //More stuff
    }
    //Even more stuff
}

Entiendo por qué esto siempre es falso ya que la cuadrícula vuelve a unir los datos y recrea la casilla de verificación a su estado predeterminado, cualquier documentación que haya encontrado para este problema con respecto a los estados de DevExpress para envolver el enlace de datos en Page_Load en if(!Page.IsPostBack) que de hecho funciona, pero rompe la clasificación y la paginación.

Estoy seguro de que tengo la solución para esto en otros proyectos que he realizado, simplemente no puedo encontrarla. ¿Qué se debe hacer en este caso?

Nota: he acortado el código lo menos posible y no lo he probado. Puede haber algunos pequeños errores con el código real, pero úselo como una guía de lo que estoy tratando de hacer y aclarará cualquier problema que las personas puedan encontrar.

EDITAR: El uso de if(!Page.IsPostBack) o if(!Page.IsCallback) en Page_Load detiene la clasificación y la paginación en la cuadrícula, eliminando esta condición significa que Checked siempre es falso. Necesito que se produzca la clasificación / paginación Y para poder leer el valor Checked de ASPxCheckBox en DataItemTemplate.

2
anothershrubery 29 dic. 2016 a las 14:35

3 respuestas

La mejor respuesta

Respuesta editada

Parece que al usar editores en DataItemTemplate tienes que usar LoadPostData() para obtener sus valores.

Uso:

for(int i = 0; i < grid.VisibleRowCount; i++)
{
    ASPxCheckBox checkbox = grid.FindRowCellTemplateControl(i, grid.Columns[0], "checkbox") as ASPxCheckBox;

    ((IPostBackDataHandler)checkbox).LoadPostData(checkbox.UniqueID, Request.Form);

    if(checkbox.Checked)
    {
        //Do conditional stuff
    }
}

En cuanto a llenar la cuadrícula, puede mantenerla dentro de Page_Load sin !IsPostBack porque no afecta a los editores (y mantendrá el filtrado / clasificación)

Puede causar problemas en otros casos, pero este no es el caso aquí.

¡Espero eso ayude! Por favor dime si tienes alguna pregunta

2
Jaqen H'ghar 4 ene. 2017 a las 21:37

Hay algunas variantes

Controlador de eventos Page_Init

Puede intentar mover su código de enlace al controlador de eventos Page_Init.

protected void Page_Init(object sender, EventArgs e)
{
    grid.DataSource = sourceTable;
    grid.DataBind();
}

El PostData del editor CheckBox se carga entre Page_Init y Page_Load, por lo que los valores de la columna CheckBox se borrarán en el evento Page_Load después de llamar al método grid.DataBind.


GridViewCommandColumn con ShowSelectCheckbox = "true"

Aquí hay otra posibilidad. Puede imitar el comportamiento deseado utilizando GridViewCommandColumn con ShowSelectCheckbox propiedad.

<dx:GridViewCommandColumn ShowSelectCheckbox="true" />

Puede utilizar el método grid.Selection.IsRowSelected para obtener las filas marcadas.
Aquí hay un ejemplo:

protected void Button1_Click(object sender, EventArgs e)
{
    //Some stuff
    for (int i = 0; i < grid.VisibleRowCount; i++)
    {
        //Other stuff                
        if (grid.Selection.IsRowSelected(i))
        {
            //Do conditional stuff
        }
        //More stuff
    }
    //Even more stuff
}
0
nempoBu4 4 ene. 2017 a las 10:30

Porque cuando hace clic en el botón, luego publica la página en el servidor y cuando la página publica en el servidor, todo el control se establece en el valor predeterminado (si no controla la propiedad isPostBack). su ordenación de control de cuadrícula se realiza en el lado del cliente pero publicando en el lado del servidor y renderizando en el lado del cliente, la clasificación se eliminó. Puedes usar Callback. Ex:

  <dx:ASPxGridView ID="grid" runat="server" ClientInstanceName="grid" OnCustomCallback="ASPxGridView1_CustomCallback">
            <Columns>
                <dx:GridViewDataColumn>
                    <DataItemTemplate>
                        <dx:ASPxCheckBox ID="checkbox" runat="server" />
                    </DataItemTemplate>
                </dx:GridViewDataColumn>
            </Columns>
   </dx:ASPxGridView>


 <dx:ASPxButton ID="btnSend" runat="server" AutoPostBack="False" Text="Send" Width="100px" ClientInstanceName="btnSend">
<ClientSideEvents Click="function(s, e) { grid.PerformCallback(); }" />
</dx:ASPxButton>

Código detrás:

if (!IsPostBack)
        {
            //Some stuff

            grid.DataSource = sourceTable;

            grid.DataBind();

            //Other stuff
        }

protected void ASPxGridView1_CustomCallback(object sender, DevExpress.Web.ASPxGridViewCustomCallbackEventArgs e)
    {
        for (int i = 0; i < grid.VisibleRowCount; i++)
        {
            //Other stuff

            ASPxCheckBox checkbox = grid.FindRowCellTemplateControl(i, grid.DataColumns[0], "checkbox") as ASPxCheckBox;

            if (checkbox.Checked) //Always false

            {

                //Do conditional stuff

            }

            //More stuff

        }
    }

Muestra la diferencia entre devolución de llamada y devolución de datos en C # Diferencia entre una devolución de datos y una devolución de llamada

0
Community 23 may. 2017 a las 12:33