Search code examples
c#asp.netdevexpressaspxgridview

ASPxGridView allow sorting and DataItemTemplate with ASPxCheckBox


I have an ASPxGridView that contains a column with a DataItemTemplate that contains an ASPxCheckBox. I then have a button outside of the grid that performs some actions based on whether the checkbox is checked.

The grid is defined as:

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

The grid is populated in Page_Load as such:

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

Where sourceTable is defined as:

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

And populated elsewhere. (The population is not important and works)

The code is implemented as such to ensure that sorting and paging works correctly on the grid, as defined in various DevExpress support topics. This is understandable. However, when we try to get the Checked value from checkbox on the button click, it is always false:

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
}

I understand why this is always false as the grid rebinds the data and recreates the checkbox to its default state, any documentation I have found for this issue regarding DevExpress states to wrap the data binding in Page_Load in if(!Page.IsPostBack) which does indeed work, but breaks sorting and paging.

I'm sure I have the solution for this in other projects I have done, I just can't find it. What should be done in this case?

Note: I have shortened the code to as little as I can possibly get away with and have not tested it. There may be some small errors with the actual code, but use it as a guide to what I am trying to do and will clarify any issues people may come across.

EDIT: Using if(!Page.IsPostBack) or if(!Page.IsCallback) in Page_Load stops sorting and paging on the grid, removing this condition means Checked is always false. I need both sorting/paging to occur AND to be able to read the Checked value of the ASPxCheckBox in the DataItemTemplate.


Solution

  • Edited answer

    It appears that when using editors in DataItemTemplate you have to use LoadPostData() to get their values.

    Use:

    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
        }
    }
    

    As for populating the grid, you can keep it inside the Page_Load without !IsPostBack because it does not affect the editors (and it will keep the filtering/sorting)

    It can cause problems in other cases but this is not the case here.

    Hope it helps! Please tell me if you have any questions