ASPxGridView 允许使用 ASPxCheckBox 进行排序和 DataItemTemplate

ASPxGridView allow sorting and DataItemTemplate with ASPxCheckBox

我有一个 ASPxGridView 包含一个列,其中 DataItemTemplate 包含一个 ASPxCheckBox。然后我在网格外有一个按钮,它根据复选框是否被选中来执行一些操作。

网格定义为:

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

网格在 Page_Load 中填充如下:

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

其中 sourceTable 定义为:

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

并在其他地方居住。 (人口不重要,工作)

代码的实现是为了确保排序和分页在网格上正常工作,如各种 DevExpress 支持主题中所定义。这是可以理解的。但是,当我们尝试在单击按钮时从 checkbox 获取 Checked 值时,它始终为 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
}

我理解为什么这总是错误的,因为网格重新绑定数据并将复选框重新创建为其默认状态,我找到的关于这个问题的任何文档都指出将数据绑定包装在 Page_Loadif(!Page.IsPostBack) 这确实有效,但会破坏排序和分页。

我确信我在我做过的其他项目中有解决这个问题的方法,但我找不到它。这种情况应该怎么办?

注意:我已将代码缩短到尽可能少的程度,并且还没有对其进行测试。实际代码可能存在一些小错误,但请将其用作我正在尝试做的事情的指南,并将澄清人们可能遇到的任何问题。

编辑:在 Page_Load 中使用 if(!Page.IsPostBack)if(!Page.IsCallback) 停止在网格上排序和分页,删除此条件意味着 Checked 始终为假。我需要 sorting/paging 发生并且能够读取 DataItemTemplate.

ASPxCheckBoxChecked

因为当你点击按钮然后页面 post 到服务器时,当页面 post 到服务器时所有控件设置为默认值(如果你不控制 isPostBack 属性) .您在客户端进行网格控制排序。但是 post 到服务器端并呈现到客户端你排序删除。您可以使用回调。 例如:

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

后面的代码:

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

        }
    }

在 c# 中显示回调和 postback 之间的区别 Difference between a Postback and a Callback

已编辑答案

似乎在 DataItemTemplate 中使用编辑器时,您必须使用 LoadPostData() 来获取它们的值。

使用:

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

至于填充网格,您可以将其保留在 Page_Load 中而无需 !IsPostBack,因为它不会影响编辑器(并且会保留 filtering/sorting)

在其他情况下可能会导致问题,但这里不是这种情况。

希望对您有所帮助!有问题请告诉我

有一些变体。

Page_Init 事件处理程序

您可以尝试将绑定代码移动到 Page_Init 事件处理程序。

protected void Page_Init(object sender, EventArgs e)
{
    grid.DataSource = sourceTable;
    grid.DataBind();
}
CheckBox 编辑器的

PostDataPage_InitPage_Load 之间加载,因此 CheckBox 列中的值将在 Page_Load 调用 grid.DataBind 方法后的事件。


GridViewCommandColumn with ShowSelectCheckbox="true"

还有一种可能。您可以通过使用 GridViewCommandColumnShowSelectCheckbox 属性.

来模仿所需的行为
<dx:GridViewCommandColumn ShowSelectCheckbox="true" />

您可以使用 grid.Selection.IsRowSelected 方法获取选中的行。
这是示例:

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
}