javascript ASP.NET 在 ListView 中隐藏 <asp:Panel>/<th>/<tr>/<td>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5171796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.NET Hiding a <asp:Panel>/<th>/<tr>/<td> inside a ListView
提问by Dan
<asp:ListView ID="ListView1" runat="server" ItemPlaceholderID="itemHolder"
OnItemCommand="listViewCmd" OnItemDeleting="OnItemDeleting"
OnItemEditing="OnItemEditing">
<LayoutTemplate>
<table class = "tblItemDetail" style = "color:Black;" width="100%" border="0" cellpadding="5">
<tr>
<asp:Panel ID="pnlNameHead" runat="server">
<th id="thName" runat="server">Name
</th>
</asp:Panel>
<th>Address
</th>
<th>Contact No.
</th>
<th>E-mail Address
</th>
<th>Edit
</th>
<th>Delete
</th>
</tr>
<asp:PlaceHolder ID="itemHolder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<asp:Panel ID="pnlName" runat="server">
<td align="center" id="tdName" runat="server">
<asp:Literal ID="lit1" runat="server" Text='<%# Eval("SupplierName") %>'></asp:Literal>
</td>
</asp:Panel>
<td align="center">
<asp:Literal ID="Literal1" runat="server" Text='<%# Eval("SupplierAdd") %>'></asp:Literal>
</td>
<td align="center">
<asp:Literal ID="Literal2" runat="server" Text='<%# Eval("SupplierContact") %>'></asp:Literal>
</td>
<td align="center">
<asp:Literal ID="Literal3" runat="server" Text='<%# Eval("SupplierEmail") %>'></asp:Literal>
</td>
<td align="center">
<asp:Button ID="Button3" runat="server" Text="Edit" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "SupplierID") %>' CommandName="edit" />
</td>
<td align="center">
<asp:Button ID="Button2" runat="server" Text="Delete" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "SupplierID") %>' CommandName="delete" />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
I got this source code for my aspx Web Form. I'm trying to hide the column for the supplier name. I've already tried many ways like:
我得到了我的 aspx Web 表单的源代码。我试图隐藏供应商名称的列。我已经尝试了很多方法,例如:
- ListView1.FindControl("pnlNameHead").Visible = false
- Panel pnlName = (Panel)ListView.FindControl("pnlName");
- pnlName.Visible = false;
- ListView1.FindControl("pnlNameHead").Visible = false
- Panel pnlName = (Panel)ListView.FindControl("pnlName");
- pnlName.Visible = false;
but I always get "Object reference not set to an instance of an object". Can anyone help me please? I've been trying to figure this out for a couple of days.
但我总是得到“对象引用未设置为对象的实例”。有人可以帮我吗?几天来,我一直试图弄清楚这一点。
回答by PhilPursglove
Don't confuse setting a Control's Visibleproperty to false with making it hidden. (Yes, I'm aware of how this sounds but bear with me).
不要将 Control 的Visible属性设置为 false 与将其设置为hidden混淆。(是的,我知道这听起来如何,但请耐心等待)。
If you set the Visible property for a control to false, this means that when the html for the page is rendered on the server, the control will not produce any markup to be included. See Control.Visibleat MSDN. This might be what you want, in which case Andrew Charlton's answer is what you need.
如果将控件的 Visible 属性设置为 false,这意味着当页面的 html 在服务器上呈现时,该控件将不会生成任何要包含的标记。请参阅MSDN 上的Control.Visible。这可能就是您想要的,在这种情况下,Andrew Charlton 的回答就是您所需要的。
If, however, you want the <th>and associated <td>elements to be present in the markup for your page in the browser, but not visible i.e. hidden, then you need to use CSS to style them with display:nonee.g.
但是,如果您希望<th>和 相关联的<td>元素出现在浏览器页面的标记中,但不可见,即隐藏,那么您需要使用 CSS 来设置它们的样式,display:none例如
<LayoutTemplate>
<table class = "tblItemDetail" style = "color:Black;" width="100%" border="0" cellpadding="5">
<tr>
<asp:Panel ID="pnlNameHead" runat="server">
<th id="thName" runat="server" style="display:none;">Name</th>
</asp:Panel>
...
</tr>
</LayoutTemplate>
<ItemTemplate>
<tr>
<asp:Panel ID="pnlName" runat="server">
<td align="center" id="tdName" runat="server" style="display:none;">
<asp:Literal ID="lit1" runat="server" Text='<%# Eval("SupplierName") %>'></asp:Literal>
</td>
</asp:Panel>
回答by Jamie Treworgy
Here are some possible reasons for the problem.
以下是问题的一些可能原因。
1) You can only make changes after the controls are created, typically in ItemDataBoundand LayoutCreatedevents. Perhaps you are trying to do it too early?
1)您只能在创建控件后进行更改,通常在ItemDataBound和LayoutCreated事件中。也许你试图做得太早?
2) There's no valid concept of wrapping a table cell in another control. I am kind of surprised this doesn't choke the parser, but maybe it works because it's just HTML. If you tried to do this with an <asp:Table>it would not work. Anyway, it won't render valid HTML - Panelcreates a divso the table element would be wrapped in a div. Anyway, there's no reason to do it this way; instead, just look for the element itself. The thand tdelements are already set to runat="server"in your example so search for them directly.
2) 没有将表格单元格包装在另一个控件中的有效概念。我有点惊讶这不会阻塞解析器,但也许它有效,因为它只是 HTML。如果你试图用 a 来做这件事,<asp:Table>它就行不通。无论如何,它不会呈现有效的 HTML -Panel创建一个div所以 table 元素将被包裹在一个 div 中。无论如何,没有理由这样做;相反,只需查找元素本身。在th和td元素已经被设置为runat="server"在你的榜样,从而直接进行搜索。
3) FindControlis not recursive. Try using a recursive implementation. Here's an extension method I use (the last parameter is just so I can share a name with FindControl, you can change the name to something else and eliminate it if you like). This is probably why FindControl isn't returning anything, since the control you're looking for is going to be in the Controls collection of another control (tr).
3)FindControl不是递归的。尝试使用递归实现。这是我使用的扩展方法(最后一个参数只是为了与 FindControl 共享名称,您可以将名称更改为其他名称并根据需要将其删除)。这可能就是 FindControl 不返回任何内容的原因,因为您要查找的控件将位于另一个控件 ( tr)的 Controls 集合中。
public static Control FindControl(this Control baseControl, string id, bool recurse)
{
foreach (Control ctl in baseControl.Controls)
{
if (ctl.ID==id)
{
return (ctl);
}
if (recurse && ctl.Controls.Count > 0)
{
Control subCtl = ctl.FindControl(id,recurse);
if (subCtl != null)
{
return (subCtl);
}
}
}
return (null);
}
Generally speaking, while this is doable, and I've tried it before, programatically changing the layout template is a nuisance and can result in a lot of condition handling in your code. If you cant just use CSS for some reason I'd make another template.
一般来说,虽然这是可行的,而且我之前也尝试过,但以编程方式更改布局模板很麻烦,并且可能会导致代码中出现大量条件处理。如果由于某种原因你不能只使用 CSS,我会制作另一个模板。
回答by Andrew Charlton
You can't access and modify things (AFAIK) in the ItemTemplate because they aren't actual controls yet; the template is just describing what each Item will contain. You could use the ItemDataBound event to go through and hide the panel in each Item after it has been created. Something like this:
您无法访问和修改 ItemTemplate 中的内容 (AFAIK),因为它们还不是实际的控件;模板只是描述每个项目将包含的内容。您可以使用 ItemDataBound 事件在每个 Item 创建后浏览和隐藏面板中的面板。像这样的东西:
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if(e.Item.ItemType == ListViewItemType.DataItem)
{
Panel pnl = (Panel)e.Item.FindControl("pnlName");
pnl.Visible = false;
}
}
The only other option is to build all of the templates dynamically or use UserControls:
唯一的其他选择是动态构建所有模板或使用 UserControls:
Dynamically change GridView item template
Edit: Just saw you had the Panel around a table cell. You could remove the panel and access the cell directly in ItemDataBound:
编辑:刚刚看到您在表格单元格周围放置了面板。您可以移除面板并直接在 ItemDataBound 中访问单元格:
HtmlControl td = (HtmlControl)e.Item.FindControl("tdName");
td.Visible = false;

