如何使用自动生成的列隐藏 ASP.NET GridView 中的列?

Posted

技术标签:

【中文标题】如何使用自动生成的列隐藏 ASP.NET GridView 中的列?【英文标题】:How to hide columns in an ASP.NET GridView with auto-generated columns? 【发布时间】: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 这么认为,但这是其中一种方式 我的网格列也是动态的,所以我需要动态隐藏它。 【参考方案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);

【讨论】:

以上是关于如何使用自动生成的列隐藏 ASP.NET GridView 中的列?的主要内容,如果未能解决你的问题,请参考以下文章

如何保存 Kendo MVC Grid 的列顺序

如何使用 ASP.NET MVC 在 Kendo UI Grid 中实现 N 级嵌套层次结构

使用自定义数据源时如何隐藏 DataGridView 的列?

如何在 Asp.Net mvc 5 的 grid.mvc 中添加两个按钮

Scrapy:FormRequest 不会自动填充 ASP.net 隐藏字段

如何在 Telerik Grid 中为 ASP.NET MVC 绑定图像