【问题标题】:How to hide columns in an ASP.NET GridView with auto-generated columns?如何使用自动生成的列隐藏 ASP.NET GridView 中的列?
【发布时间】:2011-01-06 16:20:39
【问题描述】:

GridView1.Columns.Count 即使 SqlDataSource1.DataBind() 也始终为零;

但是网格没问题

我可以的

for (int i = 0; i < GridView1.HeaderRow.Cells.Count;i++)

我在这里重命名请求标头 但是

GridView1.Columns[i].Visible = false;

无法使用,因为 GridView1.Columns.Count 为 0。

那么我该如何隐藏它们呢?

【问题讨论】:

  • 什么时候调用 GridView1.Columns.Count?如果为时过早,则尚未创建列。
  • 如果你不使用这个栏目信息,也不显示它,为什么要绑定GridView呢。
  • @Eran GridView 的列可能是自动生成的,他们想要隐藏特定列。例如,表可能有 ID、FirstName、LastName,但他们想隐藏 ID 列。
  • 因为我使用硬存储过程并且无法控制满载信息:P 这么认为,但这是其中一种方式
  • 我的网格列也是动态的,所以我需要动态隐藏它。

标签: asp.net gridview


【解决方案1】:

尝试将e.Row.Cells[0].Visible = false; 放在网格的RowCreated 事件中。

protected void bla_RowCreated(object sender, GridViewRowEventArgs e)
{
    e.Row.Cells[0].Visible = false; // hides the first column
}

这样它会自动隐藏整个列。

您无权通过 gridview 的 DataBound 事件中的 grid.Columns[i] 访问生成的列。

【讨论】:

  • 这听起来不是个好主意。每次 GridView 呈现时,都会调用 RowCreated 多次。
  • 没那么容易。 GridView 上没有 DataBound 事件,因此您必须在绑定过程的早期进行挂钩,例如 RowCreatedRowDataBound
  • 其实GridView非常有DataBound事件。
  • 我必须在那里做什么......我怎样才能取消添加一些列?
  • 就我而言,我有“自动生成”字段和“模板”字段的组合。如果我想使用这个 sn-p 来隐藏例如第三列,它会给我一个错误。因此,我添加了一个条件语句,例如 if(e.Row.Cells.Count > 2) e.Row.Cells[2].Visible = false; 并且它起作用了。
【解决方案2】:

仅当 AutoGenerateColumns=false 并且您自己手动生成列时才会填充 Columns 集合。

一个很好的解决方法是在设置 DataSource 属性并调用 DataBind() 之前自己动态填充 Columns 集合。

我有一个函数可以根据我要显示的 DataTable 的内容手动添加列。完成此操作后(然后设置 DataSource 并调用 DataBind(),我可以使用 Columns 集合并且 Count 值是正确的,并且可以按照我最初想要的方式打开和关闭列可见性。

static void AddColumnsToGridView(GridView gv, DataTable table)
{
    foreach (DataColumn column in table.Columns)
    {
        BoundField field = new BoundField();
        field.DataField = column.ColumnName;
        field.HeaderText = column.ColumnName;
        gv.Columns.Add(field);
    }
}

【讨论】:

    【解决方案3】:

    注意:此解决方案仅适用于您的 GridView 列提前知道的情况。

    听起来您正在使用GridViewAutoGenerateColumns=true,这是默认设置。我建议设置AutoGenerateColumns=false 并手动添加列:

    <asp:GridView runat="server" ID="MyGridView"
        AutoGenerateColumns="false" DataSourceID="MySqlDataSource">
        <Columns>
            <asp:BoundField DataField="Column1" />
            <asp:BoundField DataField="Column2" />
            <asp:BoundField DataField="Column3" />
        </Columns>
    </asp:GridView>
    

    并且只为您要显示的每个字段添加BoundField。这将在数​​据显示方式方面为您提供最大的灵活性。

    【讨论】:

    • 谢谢,但我的数据源每次都提供不同的列。并感谢您快速回答并纠正我的问题!
    • 是 AutoGenerateColumns=true 那么有什么方法可以使用带有 false 的动态列吗?
    【解决方案4】:

    我遇到了同样的问题 - 需要我的 GridView 控件的 AutogenerateColumns 为“真”,因为它被 SQL 数据源绑定,因此我需要隐藏一些不能在 GridView 控件中显示的列。

    实现这一点的方法是在 GridView 的 '_RowDataBound' 事件中添加一些代码,例如(假设您的 GridView 的 ID 为 = 'MyGridView'):

    protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            e.Row.Cells[<index_of_cell>].Visible = false;
        }
    }
    

    这样就可以了 ;-)

    【讨论】:

      【解决方案5】:

      您必须在网格数据绑定后执行GridView1.Columns[i].Visible = false;

      【讨论】:

      • 没有GridView.OnDataBound事件。
      • 什么时候...?如果我添加按钮并让它在那里,它永远为零。
      • GridView 实际上有一个 DataBound 事件,这就是这段代码应该去的地方。
      • protected void GridView1_DataBound(object sender, EventArgs e) { WebMsgBox.Show(GridView1.Columns.Count.ToString()); } 那是 0 ...
      • 好的。我在这里弄错了。我应该说的是:您无权访问 DataBound 事件中生成的列。
      【解决方案6】:

      尝试使用自动生成的列隐藏 ASP.NET GridView 中的列,RowDataBound/RowCreated 也可以工作。

      Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
      
          If e.Row.RowType = DataControlRowType.DataRow Or _
              e.Row.RowType = DataControlRowType.Header Then   // apply to datarow and header 
      
              e.Row.Cells(e.Row.Cells.Count - 1).Visible = False // last column
              e.Row.Cells(0).Visible = False  // first column
      
          End If
      End Sub
      
      Protected Sub GridView1_RowCreated(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowCreated
      
          If e.Row.RowType = DataControlRowType.DataRow Or _
              e.Row.RowType = DataControlRowType.Header Then
      
              e.Row.Cells(e.Row.Cells.Count - 1).Visible = False
              e.Row.Cells(0).Visible = False
      
          End If
      End Sub
      

      【讨论】:

        【解决方案7】:

        在第二列的rowdatabound 方法中

        GridView gv = (sender as GridView);
        gv.HeaderRow.Cells[2].Visible = false;
        e.Row.Cells[2].Visible = false;
        

        【讨论】:

        • @Heather 所有者接受的答案不正确。它仅隐藏列值而不隐藏列标题。如果未隐藏列标题。以前的列内容将移至该列。它对新用户有帮助
        【解决方案8】:

        @nCdy: index_of_cell 应替换为整数,对应于您希望隐藏在 .Cells 集合中的单元格的索引号。

        例如,假设您的 GridView 显示以下列:

        联系人姓名 |联系电话 |客户 ID |地址第 1 行 |邮政编码

        并且您希望不显示 CUSTOMERID 列。 由于集合索引是从 0 开始的,您的 CUSTOMERID 列的索引是..........?没错,2!!很好。 现在...猜猜你应该放什么来替换'index_of_cell'??

        【讨论】:

          【解决方案9】:

          正如其他人所说,RowDataBound 或 RowCreated 事件应该可以工作,但如果您想避免事件声明并将整个代码放在 DataBind 函数调用下方,您可以执行以下操作:

          GridView1.DataBind()
          If GridView1.Rows.Count > 0 Then
              GridView1.HeaderRow.Cells(0).Visible = False
              For i As Integer = 0 To GridView1.Rows.Count - 1
                  GridView1.Rows(i).Cells(0).Visible = False
              Next
          End If
          

          【讨论】:

            【解决方案10】:

            我发现史蒂夫·希伯特的回答很有帮助。 OP 似乎描述的问题是 GridView 上的 AutoGeneratedColumns 问题。

            在这种情况下,当您在后面的代码中绑定数据表时,您可以设置哪些列“可见”以及哪些列将隐藏。

            例如: 一个Gridview在页面上如下。

            <asp:GridView ID="gv" runat="server" AutoGenerateColumns="False" >
            </asp:GridView>
            

            然后在页面加载事件期间调用 PopulateGridView 例程后面的代码。

            protected void PopulateGridView()
            {
                DataTable dt = GetDataSource();
                gv.DataSource = dt;
                foreach (DataColumn col in dt.Columns)
                {
                    BoundField field = new BoundField();
                    field.DataField = col.ColumnName;
                    field.HeaderText = col.ColumnName;
                    if (col.ColumnName.EndsWith("ID"))
                    {
                        field.Visible = false;
                    }
                    gv.Columns.Add(field);
                }
                gv.DataBind();
            }
            

            在上面的 GridView AutoGenerateColumns 设置为 False 并且代码隐藏用于创建绑定字段。一种是通过自己的过程将数据源作为数据表获取,这里我标记为 GetDataSource()。然后循环遍历数据表的列集合。如果列名符合给定条件,您可以相应地设置绑定字段可见属性。然后将数据绑定到gridview。这与 AutoGenerateColumns="True" 非常相似,但您可以获得列的标准。当隐藏和取消隐藏的标准基于列名时,这种方法最有用。

            【讨论】:

              【解决方案11】:

              类似于接受的答案,但允许使用 ColumnNames 并绑定到 RowDataBound()。

              Dictionary<string, int> _headerIndiciesForAbcGridView = null;
              
              protected void abcGridView_RowDataBound(object sender, GridViewRowEventArgs e)
              {
                  if (_headerIndiciesForAbcGridView == null) // builds once per http request
                  {
                      int index = 0;
                      _headerIndiciesForAbcGridView = ((Table)((GridView)sender).Controls[0]).Rows[0].Cells
                          .Cast<TableCell>()
                          .ToDictionary(c => c.Text, c => index++);
                  }
              
                  e.Row.Cells[_headerIndiciesForAbcGridView["theColumnName"]].Visible = false;
              }
              

              不确定它是否适用于 RowCreated()。

              【讨论】:

                【解决方案12】:

                遍历 GridView 行并使目标列的单元格不可见。在这个例子中,我想保持第 4-6 列保持可见,所以我们跳过这些:

                foreach (GridViewRow row in yourGridView.Rows)
                   {
                     for (int i = 0; i < rows.Cells.Count; i++)
                     {
                        switch (i)
                        {
                           case 4:
                           case 5:
                           case 6:
                              continue;
                        }
                        row.Cells[i].Visible = false;
                     };
                   };
                

                然后您将需要单独删除列标题(请记住,删除标题单元格会在每次删除后更改 GridView 的长度):

                grdReportRole.HeaderRow.Cells.RemoveAt(0);

                【讨论】:

                  猜你喜欢
                  • 2010-11-28
                  • 2015-04-05
                  • 2018-10-19
                  • 2010-09-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-09-09
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多