Condicionalmente ocultar CommandField o ButtonField en Gridview

Tengo un GridView muestra registros de personas. Quiero mostrar condicionalmente un CommandField o ButtonField basado en alguna propiedad del registro subyacente. La idea es permitir que solo se ejecute un comando en personas específicas.

¿Cuál es la mejor manera de hacer esto? Preferiría una solución declarativa a una procesal.

Primero, convierta su ButtonField o CommandField a TemplateField , luego vincule la propiedad Visible del botón a un método que implemente la lógica de negocios:

            

Luego, en el código detrás, agregue el método:

 protected Boolean IsOverAgeLimit(Decimal Age) { return Age > 35M; } 

La ventaja aquí es que puedes probar el método IsOverAgeLimit bastante facilidad.

podría hacerse cuando el evento RowDataBound se dispare

  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; } } } 

Aquí hay una página de demostración

margen

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DropDownDemo._Default" %>    GridView OnRowDataBound Example   

Código detrás

 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 GetCustomers() { List results = new List(); 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; } } } 

En la demostración, el botón Editar no es visible (el marcado HTML no se envía al cliente) en aquellas filas donde la edad del cliente es 30.

Permítanme compartir mi enfoque para lo que vale. Para mí, convertir el campo de comando a un control de campo de plantilla no es una opción, ya que el campo de comando viene con funcionalidad incorporada que de otra manera tendría que crear yo mismo, por ejemplo, el hecho de que cambia a “Cancelar actualización” cuando se hace clic en Editar, y que cuando se hace clic en Editar, todas las celdas de la fila que son tags se convierten en cuadros de texto, etc.

En mi enfoque, puedes dejar el campo de comando como está, luego puedes esconderlo según sea necesario a través del código de detrás. En este ejemplo, lo escondo si el campo “Escenario” de la cuadrícula muestra el texto “Actual” para la fila relevante del evento 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; } }} 

Ocultar la columna completa de GridView

Si desea eliminar completamente la columna (es decir, no solo el botón) de la tabla, utilice un controlador de eventos adecuado, por ejemplo, para el evento OnDataBound , y luego oculte la columna apropiada en el GridView objective. Elija un evento que solo se activará una vez para este control, es decir, no OnRowDataBound .

aspx:

           

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 } } 

Convierta CommandField a TemplateField y establezca la propiedad visible del botón según el valor del campo (verdadero / falso)

  

Para controlar condicionalmente la vista de los campos Plantilla / Comando, use el evento RowDataBound de Gridview, como:

    ...        ...    

y siguientes:

 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 esto se basó en roles, podría usar el panel de vistas múltiples pero no estar seguro si podría hacer lo mismo con una propiedad del registro.

Sin embargo, puedes hacer esto a través del código. En su evento rowdatabound puede ocultar o mostrar el botón en él.

Puede ocultar un CommandField o ButtonField en función de la posición (índice) en GridView.

Por ejemplo, si su CommandField está en la primera posición (índice = 0), puede ocultarlo agregando el siguiente código en el evento RowDataBound de 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; } } 

He hecho algo muy simple para habilitar o deshabilitar el botón de comando. A continuación está mi cuadrícula

                 

En el siguiente método, he hecho los cambios

  protected void grdOrderProduct_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { foreach (ImageButton button in e.Row.Cells[5].Controls.OfType()) { if (button.CommandName == "Delete") { button.Visible = false; } } } } 
                 

Utilice este código para desactivar el botón Eliminar en la vista de cuadrícula del código que se encuentra detrás.

 protected void gv_Document_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { ((LinkButton)e.Row.Cells[7].Controls[0]).Visible = false; } }