You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DevExpress GridView分页时保存DataItemTemplate中ASPxTextBox的值

解决ASPxGridView分页时保留DataItemTemplate中文本框输入值的问题

这个问题我之前帮不少开发者解决过,本质是当你切换GridView页码触发回发/回调时,GridView会重新渲染当前页的行,DataItemTemplate里的ASPxTextBox属于动态生成的控件,默认情况下这些输入值不会自动被保留,所以返回原页面就丢了。下面给你几个实用的解决方案:

方法一:服务器端用ViewState手动保存输入值

这是最经典的服务器端方案,通过捕获文本框的输入事件,把值存到ViewState里,渲染行时再取出来赋值:

  1. 先给ASPxTextBox配置TextChanged事件和必要属性:
<dx:GridViewDataColumn FieldName="YourColumnName">
    <DataItemTemplate>
        <dx:ASPxTextBox ID="txtInput" runat="server" 
            AutoPostBack="True" 
            EnableViewState="True"
            OnTextChanged="txtInput_TextChanged">
        </dx:ASPxTextBox>
    </DataItemTemplate>
</dx:GridViewDataColumn>
  1. 在后台实现TextChanged事件,把输入值绑定到行主键保存到ViewState:
protected void txtInput_TextChanged(object sender, EventArgs e)
{
    var txtBox = sender as ASPxTextBox;
    var container = txtBox.NamingContainer as GridViewDataItemTemplateContainer;
    // 用行的主键作为唯一标识,确保不同行的文本框值不会冲突
    string rowKey = container.KeyValue.ToString();

    // 初始化存储字典
    if (ViewState["TextBoxValues"] == null)
        ViewState["TextBoxValues"] = new Dictionary<string, string>();
    
    var valueDict = (Dictionary<string, string>)ViewState["TextBoxValues"];
    valueDict[rowKey] = txtBox.Text;
}
  1. 最后在GridView的HtmlDataCellPrepared事件中,渲染行时从ViewState取值填充文本框:
protected void grid_HtmlDataCellPrepared(object sender, ASPxGridViewTableDataCellEventArgs e)
{
    // 匹配你的目标列
    if (e.DataColumn.FieldName != "YourColumnName") return;

    var txtBox = e.Cell.FindControl("txtInput") as ASPxTextBox;
    if (txtBox == null || ViewState["TextBoxValues"] == null) return;

    string rowKey = e.KeyValue.ToString();
    var valueDict = (Dictionary<string, string>)ViewState["TextBoxValues"];
    
    if (valueDict.ContainsKey(rowKey))
        txtBox.Text = valueDict[rowKey];
}

方法二:客户端用本地存储(LocalStorage)保存值

如果不想频繁触发服务器回发,用客户端脚本把值存在浏览器本地,分页后再恢复,体验更流畅:

  1. 给GridView和文本框配置客户端事件:
<dx:ASPxGridView ID="grid" runat="server" 
    ClientInstanceName="grid"
    EnableCallbacks="True">
    <ClientSideEvents EndCallback="onGridEndCallback" />
    <Columns>
        <dx:GridViewDataColumn FieldName="YourColumnName">
            <DataItemTemplate>
                <dx:ASPxTextBox ID="txtInput" runat="server" 
                    ClientInstanceName="txtInput">
                    <ClientSideEvents TextChanged="onTextBoxInput" />
                </dx:ASPxTextBox>
            </DataItemTemplate>
        </dx:GridViewDataColumn>
    </Columns>
</dx:ASPxGridView>
  1. 编写客户端脚本实现保存和恢复逻辑:
// 文本框内容变化时,把值存在LocalStorage,用行主键作为唯一标识
function onTextBoxInput(s, e) {
    var rowIndex = s.GetParent().GetParent().index;
    var rowKey = grid.GetRowKey(rowIndex);
    localStorage.setItem(`grid_${grid.name}_textbox_${rowKey}`, s.GetText());
}

// GridView分页回调完成后,恢复当前页所有文本框的值
function onGridEndCallback(s, e) {
    var visibleRows = s.GetVisibleRowsOnPage();
    for(let i = 0; i < visibleRows; i++){
        var rowKey = s.GetRowKey(i);
        var savedValue = localStorage.getItem(`grid_${grid.name}_textbox_${rowKey}`);
        if(savedValue){
            var txtBox = s.FindRowCellTemplateControl(i, "YourColumnName", "txtInput");
            if(txtBox) txtBox.SetText(savedValue);
        }
    }
}

如果只想在当前会话保存,把localStorage换成sessionStorage即可。

方法三:回调时传递值到服务器保存

如果你的GridView用的是回调模式分页(EnableCallbacks="True"),可以在分页前收集所有输入值,通过CustomCallback传递到服务器存起来,分页后再恢复:

  1. 配置GridView的客户端BeginCallback事件:
<dx:ASPxGridView ID="grid" runat="server" 
    ClientInstanceName="grid"
    EnableCallbacks="True"
    OnCustomCallback="grid_CustomCallback">
    <ClientSideEvents BeginCallback="onGridBeginCallback" />
    <!-- 列配置略 -->
</dx:ASPxGridView>
  1. 客户端脚本收集值并传递:
function onGridBeginCallback(s, e) {
    var inputValues = {};
    var visibleRows = s.GetVisibleRowsOnPage();
    for(let i = 0; i < visibleRows; i++){
        var rowKey = s.GetRowKey(i);
        var txtBox = s.FindRowCellTemplateControl(i, "YourColumnName", "txtInput");
        if(txtBox) inputValues[rowKey] = txtBox.GetText();
    }
    // 把值序列化为JSON作为参数传递
    e.customArgs["InputValues"] = JSON.stringify(inputValues);
}
  1. 服务器端CustomCallback事件中保存值:
protected void grid_CustomCallback(object sender, ASPxGridViewCustomCallbackEventArgs e)
{
    if (!string.IsNullOrEmpty(e.Parameters) && e.CustomArgs.ContainsKey("InputValues"))
    {
        string json = e.CustomArgs["InputValues"].ToString();
        var valueDict = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
        ViewState["TextBoxValues"] = valueDict;
    }
}

之后同样在HtmlDataCellPrepared事件中恢复值,和方法一的第三步一致。

注意事项

  • 确保你的GridView有设置主键列(KeyFieldName),这样才能获取到唯一的行标识;
  • 如果用服务器端方案,要保证GridView的EnableViewState="True"(默认是开启的);
  • 大数据量场景下,ViewState可能会变大,此时客户端方案会更合适。

内容的提问来源于stack exchange,提问作者Morteza Jangjoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:12:38