【问题标题】:GridView in ASP.Net -- Selecting the correct rowASP.Net 中的 GridView -- 选择正确的行
【发布时间】:2009-08-31 01:26:39
【问题描述】:

我有一个包含 GridView 的页面。该 GridView 一次分页 10 个项目。通常,我希望用户从 GridView 中选择项目并填充 FormView。这很好用。

我还想支持一个查询参数 ?ID=n,页面将在其中加载指定的项目。

如何告诉 DataGrid 或数据源将哪个项目设置为数据上下文?

我希望 DataGrid 转到正确的页面并选择项目,在 FormView 中显示指定的项目。

除了将数据源限制为特定项目之外,我无法弄清楚如何做到这一点,这让用户感到困惑。

有什么想法吗?

【问题讨论】:

  • 您是使用DetailsView 还是Fo​​rmView 控件来显示所选项目的详细信息?
  • 请注意,在问题的第一段中,我提到我正在使用 FormView 作为详细信息。

标签: asp.net gridview


【解决方案1】:

如果设置GridView的DataKey字段包含主键,有thisCodeProject文章介绍如何设置gridview的选中索引,根据记录的键值,使用扩展方法:

public static void SetRowValueValueByKey(this GridView GridView, string DataKeyValue)
{
    int intSelectedIndex = 0;
    int intPageIndex = 0;
    int intGridViewPages = GridView.PageCount;

    // Loop thru each page in the GridView
    for (int intPage = 0; intPage < intGridViewPages; intPage++)
    {
        // Set the current GridView page
        GridView.PageIndex = intPage;
        // Bind the GridView to the current page
        GridView.DataBind();
        // Loop thru each DataKey in the GridView
        for (int i = 0; i < GridView.DataKeys.Count; i++)
        {
            if (Convert.ToString(GridView.DataKeys[i].Value) == DataKeyValue)
            {
                // If it is a match set the variables and exit
                intSelectedIndex = i;
                intPageIndex = intPage;
                break;
            }
        }
    }

    // Set the GridView to the values found
    GridView.PageIndex = intPageIndex;
    GridView.SelectedIndex = intSelectedIndex;
    GridView.DataBind();
}

【讨论】:

    【解决方案2】:

    对此的正确解决方案会有所不同,具体取决于您实际从数据库中提取数据的方式。但过程几乎相同。

    1. 从数据库中获取数据以绑定到网格。
    2. 查找应显示的项目。找出它在哪一行
    3. 现在,确定应该选择哪个页面,以及应该选择该页面上的哪一行。
    4. 设置 CurrentPageIndex 并绑定网格。现在您可以设置所选项目了

    现在,关键是第 1 步和第 2 步。如果您在 SQL 级别对数据进行分页,则需要获取另一个存储过程/数据库调用来确定所选项目的“行 ID”。否则,如果您正在加载到对象集合或数据集,则可以循环并找到该项目。如果你真的需要的话,保留一个行计数器。

    不优雅,但老实说,没有一种“优雅”的方式来做到这一点。

    【讨论】:

      【解决方案3】:

      @Brian 如果我正确理解您的问题,您的意思是您已将所有内容都连接起来,用户在页面显示时单击一行。您希望如果有人直接在浏览器中键入页面的 URL 并将 ?id=x 附加到它,您应该将他引导到相关页面,选择相关行并填充 FormView基于所选记录。

      好吧,如果是这样的话,我已经做了一些东西,但让我提前警告它不是很优雅,这里是凌晨 2:30,所以请不要笑。

      假设:- 在提出的解决方案中,DataKeyNames 字段设置为源表的主键。获取的行按此键排序。我正在使用 SubSonic 3 与 SQL Server 2005 Express DB 通信(巧合的是,这是我的第一个 SS3 项目,办公室很忙尝试它)。

      表定义如下:

      Create Table StudentsTable
      ( EnrolmentNumber int not null identity primary key, 
        StudentName nvarchar(50) not null)
      

      aspx:

      <asp:GridView ID="gvStudents" runat="server" AllowPaging="True" PageSize="3"
       OnSelectedIndexChanged="GridRowChanged" OnPageIndexChanging="GridPageChanging" 
          DataKeyNames="EnrolmentNumber">
          <RowStyle BackColor="LightBlue" />
          <AlternatingRowStyle BackColor="LightCoral" />
          <Columns>
              <asp:TemplateField ShowHeader="False">
                  <ItemTemplate>
                      <asp:LinkButton ID="LinkButton1" runat="server"  
                          CommandName="Select" Text="Select"></asp:LinkButton>
                  </ItemTemplate>
              </asp:TemplateField>
          </Columns>
          <SelectedRowStyle BackColor="Red" BorderColor="Yellow" />
      </asp:GridView>
      
      <asp:FormView ID="fvSubjects" runat="server" AllowPaging="false" 
          Caption="Student" CaptionAlign="Left">
          <ItemTemplate>
              <table>
                  <tr>
                      <td>Enrolment Number</td>
                      <td><asp:Label ID="lblEN" runat="server" 
                           Text=<%# Eval("EnrolmentNumber") %> /></td>
                  </tr>
                  <tr>
                      <td>Student Name</td>
                      <td><asp:Label ID="lblName" runat="server" 
                           Text=<%# Eval("StudentName") %> /></td>
                  </tr>
              </table>
          </ItemTemplate>
      </asp:FormView>
      

      C# 代码(忍住笑):

      private IList<StudentsTable> students;
      
      protected void Page_Load(object sender, EventArgs e)
      {
          if (!IsPostBack)
          {
              LoadData();
                  CheckQueryString(students);
          }
      }
      
      private void LoadData()
      {
          students = StudentsTable.All().ToList();
          gvStudents.DataSource = students;
          gvStudents.DataBind();
      }
      
      private void CheckQueryString(IList<StudentsTable> students)
      {
          if (!Request.QueryString.HasKeys() || 
             string.IsNullOrEmpty(Request.QueryString["erno"]))
          {
              return;
          }
      
          var erno = Request.QueryString["erno"];
          int key;
          if (!int.TryParse(erno, out key))
              return;
      
          for (var i = 0; i < students.Count; i++)
          {
              if (students[i].EnrolmentNumber == key)
              {
                  SetPageSize(students, i);
      
                  break;
              }
          }
      }
      
      private void SetPageSize(IList<StudentsTable> students, int i)
      {
          var ps = gvStudents.PageSize;
          var cp = i / ps;
          var ridx = i - ps - 1;
      
          var pageEvent = new GridViewPageEventArgs(cp);
          GridPageChanging(null, pageEvent);
          gvStudents.SelectedIndex = ridx;
          GridRowChanged(null, EventArgs.Empty);
      }
      
      protected void GridRowChanged(object sender, EventArgs e)
      {
          var rIdx = gvStudents.SelectedIndex;
          if (rIdx < 0) return;
      
          var key = gvStudents.DataKeys[rIdx];
          var lst= StudentsTable.Find(x => x.EnrolmentNumber == (int)key.Value);
          SetFormView(lst);
      }
      
      private void SetFormView(IList<StudentsTable> student)
      {
          fvSubjects.DataSource = student;
          fvSubjects.DataBind();
      }
      
      protected void GridPageChanging(object sender, GridViewPageEventArgs e)
      {
          var p = e.NewPageIndex;
          if (p > gvStudents.PageCount)
              p = gvStudents.PageCount - 1;
          gvStudents.PageIndex = p;
      
          LoadData();
      }
      

      PS:- 如果你输入最后一条记录的 id 会失败。

      编辑:- 这是Project的链接

      【讨论】:

        【解决方案4】:

        ASP.NET 上的数据访问教程涉及您问题的各个方面。对我来说已经有一段时间了,但我认为这个特定教程的最后一部分可能最接近你的需要:

        http://www.asp.net/learn/data-access/tutorial-10-vb.aspx

        只需打开 GridView 的分页,一切都应该正常工作。

        【讨论】:

        • 不,他们在教程底部所做的是我已经拥有的。我想要做的是有一个查询参数进入页面,并以编程方式选择正确的项目。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-28
        • 2010-12-02
        • 2013-03-28
        • 1970-01-01
        • 1970-01-01
        • 2010-11-10
        • 1970-01-01
        相关资源
        最近更新 更多