2

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.

nempoBu4
  • 6,521
  • 8
  • 35
  • 40
anothershrubery
  • 20,461
  • 14
  • 53
  • 98

3 Answers3

2

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

Jaqen H'ghar
  • 16,186
  • 8
  • 49
  • 52
  • I have tried this but it is still not working. In testing, on `button_Click` `grid.VisibleRowCount` = 2, stepping into the for loop and `ASPxCheckBox checkbox = grid.FindRowCellTemplateControl(i, grid.Columns[0], "checkbox") as ASPxCheckBox;` is `null`. Checking `grid.VisibleRowCount` again and it is now 0. Why would this happen? – anothershrubery Jan 04 '17 at 14:22
  • Ok, it seems this is having the same issue with Valeh's solution. On `button_Click` the page has posted back and therefore not rebound to the data and therefore `grid.FindRowCellTemplateControl` returns null as does `grid.GetDataRow`. This is looking to be rather annoying. – anothershrubery Jan 04 '17 at 14:45
  • It has nothing to do with Valeh's solution. All the grid data is available (Old grid data not repopulated) at postback thats why you have the `VisibleRowCount` for example. The problem starts when you pass the data back to the server without populating the grid once again because it cannot keep its value after you send it back to the client. I'm not sure why you get the checkbox as null but I have a feeling that its another problem. I will take a look soon – Jaqen H'ghar Jan 04 '17 at 14:55
  • It is showing the same issues as Valeh's solution is what I meant. `VisibleRowCount` = 2 and therefore goes into the for loop, as soon as you try to use `grid.FindRowCellTemplateControl` or `grid.GetDataRow` it returns null and `VisibleRowCount` returns to 0. – anothershrubery Jan 04 '17 at 15:13
  • Calling `Populate` again inside the `button_Click` before the for loop at least allows `grid.FindRowCellTemplateControl` and `grid.GetDataRow` to return something, but of course it loses the `Checked` flag on the `ASPxCheckBox` – anothershrubery Jan 04 '17 at 15:16
  • @anothershrubery edited my answer please have a look thanks :) – Jaqen H'ghar Jan 04 '17 at 21:39
  • This edited solution worked! Is `LoadPostData` a well known thing? I've never heard of using it before, but it works! Cheers! – anothershrubery Jan 05 '17 at 10:07
  • Well I havent heard about it also but it seems to be the solution the DevExpress team recommend in this case. Check out their answers [here](https://www.devexpress.com/Support/Center/Question/Details/T179814) and also [here.](https://www.devexpress.com/Support/Center/Question/Details/T126552) Thanks and cheers! – Jaqen H'ghar Jan 05 '17 at 10:47
0

Because when you button click then page post to server and when page posting to server all control set to default value (If you don`t control isPostBack property). you grid control sorting doing in client side. but posting to server side and rendering to client side you sorting removed. You can use 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>

Code behind:

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

        }
    }

show difference between callback and postback in c# Difference between a Postback and a Callback

Community
  • 1
  • 1
  • Will test this soon, but it strikes me that this will still break sorting? Because the datasource isn't bound on page load? Actually and the button can't do any work here because it doesn't post back and therefore won't run the `button_Click` code. – anothershrubery Dec 29 '16 at 12:52
  • Ok your edit makes more sense. but still feels like sorting will be broken. – anothershrubery Dec 29 '16 at 13:01
  • you sort checkBox column or another one? – Valeh Mikayilzadeh Dec 29 '16 at 13:04
  • Sorting ANY column. Testing the code, I can see that my intuitions were correct. It doesn't allow sorting with the `if(!Page.IsPostBack)`, removing this condition means `Checked` is always false and changing it to `if(!Page.IsCallback)` means the grid is not populated in the `CustomCallback` method. (`grid.FindRowCellTemplateControl` returns null as does `grid.GetDataRow`) – anothershrubery Dec 29 '16 at 14:03
0

There are some variants.

Page_Init event handler

You can try to move your binding code to Page_Init event handler.

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

PostData of CheckBox editor is loaded between Page_Init and Page_Load, so the values in your CheckBox column are going to be erased in Page_Load event after calling to grid.DataBind method.


GridViewCommandColumn with ShowSelectCheckbox="true"

Here is another possibility. You can imitate the desired behavior by using GridViewCommandColumn with ShowSelectCheckbox property.

<dx:GridViewCommandColumn ShowSelectCheckbox="true" />

You can use grid.Selection.IsRowSelected method to get the checked rows .
Here is example:

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
}
nempoBu4
  • 6,521
  • 8
  • 35
  • 40
  • `Page_Init` does not work because it doesn't repopulate for sorting/paging. `GridViewCommandColumn` does not suit as it is a `DataItemTemplate` with more than just the `ASPxCheckbox` in it, and there are multiple similar columns. I just reduced the code for simplicity. – anothershrubery Jan 04 '17 at 14:16
  • @anothershrubery I can't reproduce your situation. In my test project `Page_Init` does repopulate for sorting/paging. – nempoBu4 Jan 05 '17 at 03:38
  • @anothershrubery Anyway, `LoadPostData` method as mentioned in Jaqen H'ghar's [answer](http://stackoverflow.com/a/41446795/1805640) is working too. – nempoBu4 Jan 05 '17 at 03:57