ObjectDataSource SelectMethod中的访问控制

时间:2014-09-02 14:32:35

标签: c# asp.net webforms controls objectdatasource

使用ObjectDataSource考虑以下Webforms代码来填充GridView:

Default.aspx的

<asp:GridView ID="GV" DataSourceID="ODS" runat="server"/>
<asp:ObjectDataSource ID="ODS"  TypeName="WebApplication.Default" SelectMethod="GetModels" runat="server" />
<asp:Label ID="Label" runat="server"/>

Default.aspx.cs

    private static readonly List<Model> Models; 

    static Default()
    {
        Models = new List<Model>
        {
            new Model {Id = 1, Name = "Foo"},
            new Model {Id = 2, Name = "Bar"},
            new Model {Id = 3, Name = "Foo"},
            new Model {Id = 4, Name = "Bar"}
        };
    }

    public List<Model> GetModels()
    {
        var listsizeCap = 3;
        var totalCount = Models.Count;
        if (totalCount > listsizeCap)
        {
            // Label is null!
            Label.Text = string.Format("The grid only shows the first {0} results of a total of {1}", listsizeCap, totalCount);
        }

        return Models.Take(listsizeCap).ToList();
    }

我需要限制数据源返回的项目数量,并显示标签已限制项目的数量。

但是,当我到达GetModels方法时,Label为空。

知道如何在ObjectDataSource select方法中设置Control的值吗?

2 个答案:

答案 0 :(得分:1)

您是在谈论分页数据源吗?如果是这种情况,您可以使用

  

EnablePaging =&#34;真&#34;

     

SelectCountMethod =&#34;&#34;

您在此处声明的方法将返回此方法应返回的总记录数。你需要自己编写这个方法,但它应该与你的select方法相同。然后你可以使用:

  

MaximumRowsParameterName =&#34;&#34;

     

StartRowIndexParameterName =&#34;&#34;

这些将由ObjectDataSource的select方法使用,因为它是最后两个参数。如果要在ObjectDataSource中声明变量,则实际上不会添加它们,这将自动传递。将您在此处设置的名称添加到实际方法减速度中。您将根据这些值将您的选择代码调整为页面。

修改:将上面的项目保留为完整性。问题的答案应该如下。

如果您正在使用ObjectDataSource的分页方法,则不应尝试从select方法更改页面元素。你应该分离这个逻辑并依赖于ObjectDataSource的onSelected方法。具体来说,您将获得您声明的SelectCountMethod的返回值。你可以做的就是在页面后面的代码中添加这样的东西。

public int recordsReturned;
public int recordCount;

protected void nameOfYourOnSelectedMethod(object sender, ObjectDataSourceStatusEventArgs e)
{
// check if this call is from the Select or SelectCount method
if (e.ExecutingSelectCount) {
  // logic here will be used for setting the label
  recordCount = e.ReturnValue;
  Label.Text = "The grid only shows the first " + recordsReturned.ToString()  + " results of a total of " + recordCount.ToString();
}
else {
  // logic here is to get the amount of records returned
  // you just want to save the value here
  recordsReturned = e.ReturnValue.Count();
}

我自己没有尝试过代码,但它应该可以运行。

答案 1 :(得分:1)

对于所有ASP.NET而言,TypeName上的ObjectDataSource属性指的是一个简单的POCO。就我而言,它恰好是Page类。无论如何,当ASP.NET调用GetModels时,没有任何页面硬连线完成,因此其他控件(例如Label)永远不会在幕后初始化。

我通过在HttpContext.Current.Items添加临时状态找到了解决方案。

然后

GetModels成为:

public List<Model> GetModels()
{
    var listsizeCap = 3;
    var totalCount = Models.Count;
    if (totalCount > listsizeCap)
    {
        HttpContext.Current.Items["LabelToSet"] = string.Format("The grid only shows the first {0} results of a total of {1}", listsizeCap, totalCount);
    }

    return Models.Take(listsizeCap).ToList();
}

使用OnDataBound事件更新Default.aspx:

<asp:GridView ID="GV" DataSourceID="ODS" OnDataBound="GV_DataBound" runat="server"/>

HttpContext读取值并将其分配给Label

protected void GV_DataBound(object sender, EventArgs e)
{
    Label.Text = HttpContext.Current.Items["LabelToSet"].ToString();
}