Cacher conditionnellement CommandField ou ButtonField dans Gridview
j'ai un GridView
affichage des dossiers des personnes. Je veux conditionnellement afficher un CommandField
ou ButtonField
basé sur une propriété du document sous-jacent. L'idée est de n'autoriser une commande doit être effectuée sur des personnes spécifiques.
Quelle est la meilleure façon de le faire? Je préfère déclaratif solution à une procédure.
10 réponses
tout D'abord, convertissez votre ButtonField
ou CommandField
TemplateField
, alors liez le Visible
propriété du bouton à une méthode qui implémente la logique métier:
<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>
puis, dans le code derrière, ajouter dans la méthode:
protected Boolean IsOverAgeLimit(Decimal Age) {
return Age > 35M;
}
L'avantage ici est que vous pouvez tester!--6--> méthode assez facilement.
il pourrait être fait lorsque l' RowDataBound
feux d'événement
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;
}
}
}
Voici une page de démonstration
balise
<%@ 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>
Code Derrière
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;
}
}
}
dans la démo, le bouton Edit n'est pas Visible (le balisage HTML N'est pas envoyé au client) dans les lignes où l'âge du client est de 30 ans.
Permettez-moi de partager mon approche pour ce que ça vaut. Pour moi, convertir le champ de commande en contrôle de champ templat n'est pas une option, car le champ de commande est livré avec une fonctionnalité intégrée que je devrais autrement créer moi-même, par exemple le fait qu'il change en "Update Cancel" quand Edit est cliqué, et que lorsque Edit est cliqué, toutes les cellules de la ligne qui sont des étiquettes deviennent des boîtes de texte, etc.
dans mon approche, vous pouvez quitter le champ de commandement tel quel, puis vous peut le cacher au besoin via le code derrière. Dans cet exemple, je le cache si le champ "scénario" de la grille montre le texte "réel" pour la ligne pertinente de L'événement RowDataBound.
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;
}
}}
masquer toute la colonne GridView
si vous voulez supprimer complètement la colonne (pas seulement le bouton) de la table, utilisez alors un gestionnaire d'événements approprié, par exemple pour le OnDataBound
événement, puis masquer la colonne appropriée sur la cible GridView
. Choisissez un événement qui ne se déclenchera qu'une fois pour ce contrôle, c.-à-d. pas 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
}
}
convertissez le champ de commande en champ TemplateField et définissez la propriété visible du bouton en fonction de la valeur du champ (true/false)
<asp:Button ID="btnSelect"
runat="server" Text="Select"
Visible='<%# DataBinder.Eval(Container.DataItem,"IsLeaf") %>'/>
pour contrôler conditionnellement la vue des Champs Template / Command, utilisez RowDataBound event de Gridview, comme:
<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>
et suivant:
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;
}
}
si cela est basé sur les rôles, vous pouvez utiliser le panneau multiview, mais pas sûr si vous pouvez faire la même chose contre une propriété du document.
cependant, vous pouvez le faire par code. Dans votre événement rowdatabound, vous pouvez cacher ou afficher le bouton.
Vous pouvez cacher un champ de commande ou ButtonField basé sur la position (index) dans le GridView.
par exemple, si votre champ de commande est dans la première position (index = 0), Vous pouvez le cacher en ajoutant le code suivant dans L'événement RowDataBound du GridView:
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;
}
}
j'ai fait une chose très simple pour activer ou désactiver le bouton de commande. Ci-dessous est ma grille
<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" />
Dans la méthode suivante, j'ai fait les modifications
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;
}
}
}
}
<asp:GridView ID="gv_Document" CssClass="gridstyle" runat="server" OnRowDataBound="gv_Document_RowDataBound" AutoGenerateColumns="false" DataKeyNames="SourceGUID,Source,FilePath" ShowHeaderWhenEmpty="false" OnRowDeleting="gv_Document_RowDeleting">
<Columns>
<asp:BoundField HeaderText="ItemID" DataField="ItemID" ItemStyle-CssClass="hidden-field" HeaderStyle-CssClass="hidden-field" />
<asp:BoundField HeaderText="SourceGUID" DataField="SourceGUID" ItemStyle-CssClass="hidden-field" HeaderStyle-CssClass="hidden-field" />
<asp:BoundField HeaderText="Source" DataField="Source" ItemStyle-CssClass="hidden-field" HeaderStyle-CssClass="hidden-field" />
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:HyperLink ID="hyperLink" runat="server" Target="_blank" NavigateUrl='<%# Bind("FilePath")%>'
Text='<%# Bind("FileName")%>'> </asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Type" DataField="FileExtension" ItemStyle-CssClass="hidden-field" HeaderStyle-CssClass="hidden-field" />
<asp:BoundField HeaderText="Content type" DataField="FileMimeType" ItemStyle-CssClass="hidden-field" HeaderStyle-CssClass="hidden-field" />
<asp:BoundField HeaderText="File Path" DataField="FilePath" ItemStyle-CssClass="hidden-field" HeaderStyle-CssClass="hidden-field" />
<asp:CommandField ShowDeleteButton="True" DeleteText="Delete" />
</Columns>
Utilisez ce code pour désactiver le bouton supprimer dans gridview de code derrière.
protected void gv_Document_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
((LinkButton)e.Row.Cells[7].Controls[0]).Visible = false;
}
}