简体   繁体   English

如何避免每次回发都重新加载GridView数据?

[英]How to avoid reloading GridView data every postback?

I have a GridView which loads some data on Load like this: 我有一个GridView可以像这样在Load上加载一些数据:

protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        if (!Page.IsPostBack)
        {
            DataTable dataSource = LoadObjects();
            gvObjects.DataSource = dataSource;
        }
    }

I've also added a SelectedIndexChanged event handler where I want to perform some functions whenever a row is selected. 我还添加了SelectedIndexChanged事件处理程序,在该处理程序中,我希望每当选定一行时执行一些功能。 The problem is that unless I remove the IsPostBack check from the OnLoad method, when a row is selected the GridView.SelectedRow attribute is not the row I selected. 问题是,除非我从OnLoad方法中删除IsPostBack检查,否则当选择一行时,GridView.SelectedRow属性不是我选择的行。

Ideally I don't want to load all my data from the database on each postback. 理想情况下,我不想在每次回发时从数据库加载我的所有数据。 Are there any best-practices to get the selected row during the SelectedIndexChanged event without reloading everything again? 是否有任何最佳做法来在SelectedIndexChanged事件期间获取所选行,而无需再次重新加载所有内容?

Thanks. 谢谢。

By default the GridView selects a row based on Index. 默认情况下, GridView根据索引选择一行。 Try instructing the GridView to select rows based on Keys. 尝试指示GridView根据键选择行。

Set the EnablePersistedSelection property to true so that the row selection is based on data-key values. EnablePersistedSelection属性设置为true ,以使行选择基于数据键值。 Now if your earlier selected row gets its index or position changed in any way it will remain selected. 现在,如果您先前选择的行以任何方式更改其索引或位置,它将保持选中状态。

I usually have my GridViews full of dynamic controls which can be a lot of "fun", if they're not recreated on PostBack they don't work. 通常,我的GridViews充满了动态控件,这些控件可能很多“有趣”,如果未在PostBack上重新创建它们,则它们将无法工作。

You seem only interested in the SelectedRow but this solution will also work and help save you a headache if you start getting fancy with dynamic controls 您似乎只对SelectedRow感兴趣,但是如果您开始喜欢动态控件,那么此解决方案也将起作用并帮助您避免头痛

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    gvObjects.DataSource = LoadCachedObjects();
    gvObjects.DataBind();
}


private DataTable LoadCachedObjects()
{
    var result = new DataTable();
    if ((Session["CachedDataTable"] != null) && (IsPostBack))
    {
        //cached DataTable will only be used on PostBack
        result = Session["CachedDataTable"] as DataTable;
    }
    if (result.Rows.Count == 0)
    {
        result = LoadObjects(); //Get data from the database
        Session["CachedDataTable"] = result;
    }
    return result;
}

This only loads the data from the session when a postback event occurs, so you'll have one initial database hit on page load. 仅在发生回发事件时才从会话中加载数据,因此页面加载时将有一个初始数据库命中。 Also if you end up using that code on other pages you don't have to be massively concerned about giving the session variable a unique name 同样,如果您最终在其他页面上使用了该代码,则不必太在意为会话变量赋予唯一名称

If you can't prevent postbacks, you will obviously have to reload. 如果您不能阻止回发,则显然必须重新加载。 So the solution would be to try to reload as little as possible. 因此,解决方案是尝试尽可能少地重新加载。

A good way is to cache data somewhere, for example in the Session object. 一个好的方法是将数据缓存在某个地方,例如在Session对象中。 But only cache the primary keys together with a result index (1 to total result count). 但是只将主键和结果索引一起缓存(结果总数为1)。 This way, you can quickly retrieve the primary keys that you need data for, and get only that data freshly from the database. 这样,您可以快速检索需要数据的主键,并仅从数据库中重新获取该数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM