有条件地隐藏GridView中的CommandField或ButtonField
我有一个GridView
显示人员logging。 我想有条件地显示基于logging的某些属性的CommandField
或ButtonField
。 这个想法是只允许对特定的人执行命令。
什么是最好的方法来做到这一点? 我更喜欢一个程序化的声明式解决scheme。
首先,将ButtonField
或CommandField
转换为TemplateField
,然后将button的Visible
属性绑定到实现业务逻辑的方法:
<asp:GridView runat="server" ID="GV1" AutoGenerateColumns="false"> <Columns> <asp:BoundField DataField="Name" HeaderText="Name" /> <asp:BoundField DataField="Age" HeaderText="Age" /> <asp:TemplateField> <ItemTemplate> <asp:Button runat="server" Text="Reject" Visible='<%# IsOverAgeLimit((Decimal)Eval("Age")) %>' CommandName="Select"/> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
然后,在后面的代码中,添加方法:
protected Boolean IsOverAgeLimit(Decimal Age) { return Age > 35M; }
这里的优点是你可以很容易地testingIsOverAgeLimit
方法。
它可以在RowDataBound
事件触发时完成
protected void GridView_RowDataBound(Object sender, GridViewRowEventArgs e) { if(e.Row.RowType == DataControlRowType.DataRow) { // Hide the edit button when some condition is true // for example, the row contains a certain property if (someCondition) { Button btnEdit = (Button)e.Row.FindControl("btnEdit"); btnEdit.Visible = false; } } }
这是一个演示页面
标记
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DropDownDemo._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>GridView OnRowDataBound Example</title> </head> <body> <form id="form1" runat="server"> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"> <Columns> <asp:BoundField HeaderText="Name" DataField="name" /> <asp:BoundField HeaderText="Age" DataField="age" /> <asp:TemplateField> <ItemTemplate> <asp:Button ID="BtnEdit" runat="server" Text="Edit" /> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </form> </body> </html>
代码在后面
using System; using System.Collections.Generic; using System.Web.UI.WebControls; namespace GridViewDemo { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { GridView1.DataSource = GetCustomers(); GridView1.DataBind(); } protected override void OnInit(EventArgs e) { GridView1.RowDataBound += new GridViewRowEventHandler(GridView1_RowDataBound); base.OnInit(e); } void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType != DataControlRowType.DataRow) return; int age; if (int.TryParse(e.Row.Cells[1].Text, out age)) if (age == 30) { Button btnEdit = (Button) e.Row.FindControl("btnEdit"); btnEdit.Visible = false; } } private static List<Customer> GetCustomers() { List<Customer> results = new List<Customer>(); results.Add(new Customer("Steve", 30)); results.Add(new Customer("Brian", 40)); results.Add(new Customer("Dave", 50)); results.Add(new Customer("Bill", 25)); results.Add(new Customer("Rich", 22)); results.Add(new Customer("Bert", 30)); return results; } } public class Customer { public string Name {get;set;} public int Age { get; set; } public Customer(string name, int age) { Name = name; Age = age; } } }
在演示中,在客户年龄为30岁的行中,“编辑button”不可见 (HTML标记不会发送到客户端)。
请允许我分享一下我的方法。 对于我而言,将命令字段转换为模板字段控件不是一个选项,因为命令字段带有内置function,否则我必须创build自己,例如单击“编辑”时更改为“更新取消”的事实,以及当单击“编辑”时,标签行中的所有单元格变成文本框等等。
在我的方法中,您可以按原样离开命令字段,然后可以通过后面的代码隐藏它。 在此示例中,如果网格的“scheme”字段显示RowDataBound事件的相关行的文本“Actual”,则隐藏它。
protected void gridDetail_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { if (((Label)e.Row.FindControl("lblScenario")).Text == "Actual") { LinkButton cmdField= (LinkButton)e.Row.Cells[0].Controls[0]; cmdField.Visible = false; } }}
将CommandField转换为TemplateField,并根据字段值(true / false)设置button的visible属性
<asp:Button ID="btnSelect" runat="server" Text="Select" Visible='<%# DataBinder.Eval(Container.DataItem,"IsLeaf") %>'/>
隐藏整个GridView列
如果要从表中完全删除列(即不仅仅是button),则使用适当的事件处理程序(例如,用于OnDataBound
事件),然后在目标GridView
上隐藏适当的列。 select一个事件,只会触发一次这个控制,即不是OnRowDataBound
。
ASPX:
<asp:GridView ID="grdUsers" runat="server" DataSourceID="dsProjectUsers" OnDataBound="grdUsers_DataBound"> <Columns> <asp:TemplateField HeaderText="Admin Actions"> <ItemTemplate><asp:Button ID="btnEdit" runat="server" text="Edit" /></ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="FirstName" HeaderText="First Name" /> <asp:BoundField DataField="LastName" HeaderText="Last Name" /> <asp:BoundField DataField="Telephone" HeaderText="Telephone" /> </Columns> </asp:GridView>
aspx.cs:
protected void grdUsers_DataBound(object sender, EventArgs e) { try { // in this case hiding the first col if not admin if (!User.IsInRole(Constants.Role_Name_Admin)) grdUsers.Columns[0].Visible = false; } catch (Exception ex) { // deal with ex } }
要有条件地控制模板/命令字段的视图,请使用Gridview的RowDataBound事件,如:
<asp:GridView ID="gv1" OnRowDataBound="gv1_RowDataBound" runat="server" AutoGenerateColumns="False" DataKeyNames="Id" > <Columns> ... <asp:TemplateField HeaderText="Order Status" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center"> <ItemTemplate> <asp:Label ID="lblOrderStatus" runat="server" Text='<%# Bind("OrderStatus") %>'></asp:Label> </ItemTemplate> <HeaderStyle HorizontalAlign="Center"></HeaderStyle> <ItemStyle HorizontalAlign="Center"></ItemStyle> </asp:TemplateField> ... <asp:CommandField ShowSelectButton="True" SelectText="Select" /> </Columns> </asp:GridView>
和以下:
protected void gv1_RowDataBound(object sender, GridViewRowEventArgs e) { Label lblOrderStatus=(Label) e.Row.Cells[4].FindControl("lblOrderStatus"); if (lblOrderStatus.Text== "Ordered") { lblOrderStatus.ForeColor = System.Drawing.Color.DarkBlue; LinkButton bt = (LinkButton)e.Row.Cells[5].Controls[0]; bt.Visible = false; e.Row.BackColor = System.Drawing.Color.LightGray; } }
如果这是基于angular色,则可以使用多视图面板,但不确定是否可以对logging的属性执行相同的操作。
不过,你可以通过代码来做到这一点。 在你的rowdatabound事件中,你可以隐藏或显示button。
您可以根据GridView中的位置(索引)隐藏CommandField或ButtonField。
例如,如果您的CommandField位于第一个位置(index = 0),则可以隐藏它,并在GridView的事件RowDataBound中添加以下代码:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { ((System.Web.UI.Control)e.Row.Cells[0].Controls[0]).Visible = false; } }
我做了一个非常简单的事情来启用或禁用命令button。 以下是我的网格
<asp:GridView ID="grdOrderProduct" runat="server" TabIndex="1" BackColor="White" BorderColor="#CEC9EF" CssClass="table table-striped dataTable table-bordered" OnRowEditing="grdOrderProduct_RowEditing" OnRowUpdating="grdOrderProduct_RowUpdating" OnRowDeleting="grdOrderProduct_RowDeleting" OnRowDataBound="grdOrderProduct_RowDataBound" Width="100%" CellPadding="3" CellSpacing="1" BorderWidth="0" AutoGenerateColumns="False"> <HeaderStyle /> <AlternatingRowStyle /> <Columns> <asp:BoundField DataField="ProductSKU" ReadOnly="true" HeaderText="Product SKU" HeaderStyle-CssClass="headTb4" /> <asp:BoundField DataField="ProductName" ReadOnly="true" HeaderText="ProductName" HeaderStyle-CssClass="headTb4" /> <asp:BoundField DataField="QTY" HeaderText="QTY" HeaderStyle-CssClass="headTb4" /> <asp:BoundField DataField="Discount" HeaderText="Discount %" HeaderStyle-CssClass="headTb4" /> <asp:BoundField DataField="TPrice" HeaderText="MRP" ReadOnly="true" HeaderStyle-CssClass="headTb4" /> <asp:CommandField ShowEditButton="true" ButtonType="Image" EditImageUrl="~/Images/edit.png" UpdateImageUrl="~/Images/gear.png" CancelText=" " HeaderStyle-CssClass="headTb4" ShowDeleteButton="true" DeleteImageUrl="~/Images/delete.png" HeaderText="Action" ItemStyle-HorizontalAlign="Center"> <HeaderStyle CssClass="headTb4" /> <ItemStyle HorizontalAlign="Center" /> </asp:CommandField> </Columns> <AlternatingRowStyle CssClass="odd" /> <PagerStyle HorizontalAlign="Center" VerticalAlign="Top" Wrap="False" />
在下面的方法中,我已经做了更改
protected void grdOrderProduct_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { foreach (ImageButton button in e.Row.Cells[5].Controls.OfType<ImageButton>()) { if (button.CommandName == "Delete") { button.Visible = false; } } } }