如何在GridView中隐藏TemplateField列

39

我该如何在 GridView 中隐藏一个 TemplateField 列?

我尝试了以下方法:

<asp:TemplateField ShowHeader="False" Visible='<%# MyBoolProperty %>' >
<ItemTemplate>
    <asp:LinkButton ID="attachmentButton" runat="server" ... />
</ItemTemplate>

但它没有生效,而是给出了以下错误:

数据绑定表达式仅支持具有 DataBinding 事件的对象。System.Web.UI.WebControls.TemplateField 没有 DataBinding 事件。

我还尝试以编程方式隐藏它,但似乎不可能通过名称获取列,因为 TemplateField 列没有名称。

9个回答

60
protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
         e.Row.Cells[columnIndex].Visible = false;
}


如果您不喜欢硬编码的索引,我唯一能建议的解决方法是为GridViewColumn提供一个 HeaderText,然后使用该 HeaderText 查找相应的列。

protected void UsersGrid_RowCreated(object sender, GridViewRowEventArgs e)
{
    ((DataControlField)UsersGrid.Columns
            .Cast<DataControlField>()
            .Where(fld => fld.HeaderText == "Email")
            .SingleOrDefault()).Visible = false;
}

4
谢谢,但我想知道如何获取它的索引,我不喜欢硬编码的索引。 - Homam
@naveen e.Row.Cells[columnIndex].Visible = false; 可以完美地隐藏列数据... 如果我还想隐藏相应的Header Template,该怎么办? - Gk_999
@naveen 你使用DataControlField的解决方案在数据绑定后也可以工作,唯一的建议是以这种方式放置列的标题: <asp:TemplateField HeaderText ="电子邮件"> - Caesar
如果HeaderText进行本地化了呢? - A-Sharabiani
1
@A-Sharabiani:好久不见了。我有时间会检查的。 - naveen
显示剩余2条评论

10
For Each dcfColumn As DataControlField In gvGridview.Columns
    If dcfColumn.HeaderText = "ColumnHeaderText" Then
        dcfColumn.Visible = false                    
    End If
Next

10

在我看来,将Visible属性设置为false的行将无法访问,它们被从DOM中删除而不是隐藏,因此我也使用了Display: None方法。在我的情况下,我想要一个包含行键的隐藏列。对我来说,这种声明性方法比一些使用代码的方法更清晰简洁。

<style>
   .HiddenCol{display:none;}                
</style>


 <%--ROW ID--%>
      <asp:TemplateField HeaderText="Row ID">
       <HeaderStyle CssClass="HiddenCol" />
       <ItemTemplate>
       <asp:Label ID="lblROW_ID" runat="server" Text='<%# Bind("ROW_ID") %>'></asp:Label>
       </ItemTemplate>
       <ItemStyle HorizontalAlign="Right" CssClass="HiddenCol" />
       <EditItemTemplate>
       <asp:TextBox ID="txtROW_ID" runat="server" Text='<%# Bind("ROW_ID") %>'></asp:TextBox>
       </EditItemTemplate>
       <FooterStyle CssClass="HiddenCol" />
      </asp:TemplateField>

7
GridView1.Columns[columnIndex].Visible = false;

4

试试这个

.hiddencol
    {
        display:none;
    }
    .viscol
    {
        display:block;
    }

在GridView的RowCreated事件中加入以下代码。
protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
     if (e.Row.RowType == DataControlRowType.DataRow)
     {
         e.Row.Cells[0].CssClass = "hiddencol";
     }
     else if (e.Row.RowType == DataControlRowType.Header)
     {
         e.Row.Cells[0].CssClass = "hiddencol";
     }
}

3
如果你只关心屏幕上的可见性,那么这样做就没问题了。但是如果你要显示/隐藏私人信息(例如 StackOverflow 的真实姓名),那么你不能仅仅将其隐藏在客户端上,它根本不能被发送到客户端。 - Nathan Koop

2

我有所不知吗?

如果您无法在TemplateField上设置可见性,请在其内容上进行设置。

<asp:TemplateField>
  <ItemTemplate>
    <asp:LinkButton Visible='<%# MyBoolProperty %>' ID="foo" runat="server" ... />
  </ItemTemplate>
</asp:TemplateField> 

如果您的内容较为复杂,可以将其放入一个div中,并设置div的可见性。
<asp:TemplateField>
  <ItemTemplate>
    <div runat="server" visible='<%# MyBoolProperty  %>' >
      <asp:LinkButton ID="attachmentButton" runat="server" ... />
    </div>
  </ItemTemplate>
</asp:TemplateField> 

问题在于您无法将<div>放置在模板字段之外。 - Fandango68
1
对我来说,这个div显然在templatefield里面。无论如何,我进行了编辑,使其更加明显。 - frenchone

1
protected void gvLogMessageDetail_RowDataBound(object sender, GridViewRowEventArgs e)  
    { 
      if (e.Row.RowType == DataControlRowType.Header)   
        {  
            if (rdlForImportOrExport.SelectedIndex == 1)  
            {  
                e.Row.Cells[3].Visible = false;  
                e.Row.Cells[4].Visible = false;  
                e.Row.Cells[5].Visible = false;  
            }  
            else  
            {  
                e.Row.Cells[3].Visible = true;  
                e.Row.Cells[4].Visible = true;  
                e.Row.Cells[5].Visible = true;  
            }  
        }    
        if (e.Row.RowType == DataControlRowType.DataRow) //skip header row  
        {  
            try  
            {  
                if (rdlForImportOrExport.SelectedIndex == 1)  
                {  
                    e.Row.Cells[3].Visible = false;  
                    e.Row.Cells[4].Visible = false;  
                    e.Row.Cells[5].Visible = false;  
                }  
                else  
                {  
                    e.Row.Cells[3].Visible = true;  
                    e.Row.Cells[4].Visible = true;  
                    e.Row.Cells[5].Visible = true;  
                }  
                }  
            catch  
            {  
                ClientScript.RegisterStartupScript(GetType(), "Expand", "<SCRIPT   LANGUAGE='javascript'>alert('There is binding problem in child grid.');</script>");  
            }  
        }  
    }  

1
一种使用列名的轻微改进,个人认为:
    Private Sub GridView1_Init(sender As Object, e As System.EventArgs) Handles GridView1.Init
    For Each dcf As DataControlField In GridView1.Columns
        Select Case dcf.HeaderText.ToUpper
            Case "CBSELECT"
                dcf.Visible = Me.CheckBoxVisible
                dcf.HeaderText = "<small>Select</small>"
        End Select
    Next
End Sub

这允许控制多列。 我最初使用“技术”列名,与控件名称相匹配。 这使得在ASCX页面中明显它是一个控件列。 然后根据需要替换名称以进行演示。 如果我在生产中发现奇怪的名称,我知道我跳过了某些步骤。 “ToUpper”避免了大小写问题。 最后,在任何帖子上运行一次,而不是在创建行时捕获事件。

0

这是另一种方法来完成它并验证空值

DataControlField dataControlField = UsersGrid.Columns.Cast<DataControlField>().SingleOrDefault(x => x.HeaderText == "Email");
            if (dataControlField != null)
                dataControlField.Visible = false;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接