0

我正在为 GridView 使用 SelectMethod,我使用 ModelBnding。简化视图:

<asp:GridView AllowPaging="True" 
        AllowSorting="True"
        runat="server"
        PageSize="10" 
        SelectMethod="GetRedirections"
        ID="rediretionGrid" AutoGenerateColumns="False" 
        ItemType="TTC.TT.Entities.ViewModels.Redirections.RedirectionView"
        DataKeyNames="Id"
        >
...
</asp:GridView>

后面的代码:

public IQueryable<RedirectionView> GetRedirections2([Control] string filter)
{
    var mappings = RedirectionService.GetRedirections().Where(x => x.Source.Contains(filter)).AsQueryable();

    // Setting PageIndex to 0 doesn't solve the problem.
    rediretionGrid.PageIndex = 0;
    return mappings;
}

当过滤器设置为流行的东西时,会返回多个结果(例如 2000),不幸的是,当他将过滤器更改为不流行的东西并且结果不多时,用户能够转到不同的分页页面(例如他将转到第 30 页)返回(例如 3 个结果) DataGrid 将显示“未找到任何项目”的信息,因为 DataGrid 保留了用户在远处页面 (30) 上的信息,并且他正在尝试显示该页面以进行新过滤. 如果用户在第一页,一切正常。什么是解决方法?如何在更改过滤器时将用户发送到第一页(或将显示结果的任何其他页面,通常是最后一页),或者采取措施避免 DataGrid 没有显示任何内容的情况,即使有多个记录被发现。

我将 PageIndex 设置为 0 的实验并没有解决问题(它们引入了更多问题,但我只想提一下,以防有人提出这个答案)。当我将 PageIndex 设置为 0 时,仍然 DataGrid 没有显示任何结果。

说清楚,我知道如何解决这个问题,但实施时间很长,我不敢相信 M$ 可能看不到这种情况发生。因为如果我被迫实现额外的事件监听器并添加自定义逻辑来为我处理这种情况,使用 ModelBinding 和 SelectMethod 是没有意义的,这是不值得的,因为编写这个自定义逻辑需要更多时间,然后不使用 SelectMethod 和 ModelBinding。

更新: SelectMethod 返回类型的简单实验表明,当我将 GetRedirection2 方法的定义更改为:

public IEnumerable<RedirectionView> GetRedirections2(int maximumRows, int startRowIndex, out int totalRowCount, string sortByExpression, [Control] string filter)

我自己进行分页和排序,并尝试将 PageIndex 设置为 0,例如:

if (startRowIndex > totalRowCount)
{
    rediretionGrid.PageIndex = 0;
}

现在设置它并不能解决问题,因为它已经太迟了。我相信 DataGrid 仍然存储它的 startRowIndex 并在返回后使用它来处理数据。最后它使用 PageIndex 并假装显示第 0 页,而实际上它显示的是不同的页面。所以我想要的是一种改变 startRowIndex 的方法,比如将参数标记为 out 就像处理 totalRowCount 一样。

4

1 回答 1

0

我能想到的最简单和最快的实现方式,但就我希望看到的而言,一种糟糕的方式是重新加载整页。所以,我回到了我原来的 GetRedirections2 方法定义。出于可见性原因,简化了以下代码:

public IQueryable<RedirectionView> GetRedirections2([Control] string filter)
{
    var mappings = RedirectionService.GetRedirections().Where(x => x.Source.Contains(filter));

    // This is a terrible hack to redirect user to a first page.
    if (rediretionGrid.PageIndex * rediretionGrid.PageSize > mappings.Count)
    {
        Response.Redirect(Paths.Redirections.Index_aspx + "?filterValue=" + filter);
    }
    return mappings.AsQueryable();
}

在 Page_Load 中:

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack) return;
    var filterValue = Request.QueryString["filterValue"];
    filter.Text = filterValue;
}

我希望有一种正确的方法,不需要像这样实施黑客攻击:(

于 2013-11-06T12:08:28.820 回答