Условно скрыть CommandField или ButtonField в Gridview - PullRequest
26 голосов
/ 22 сентября 2009

У меня есть GridView отображение записей о людях. Я хочу условно показать CommandField или ButtonField на основе какого-либо свойства базовой записи. Идея состоит в том, чтобы разрешить выполнение команды только определенным людям.

Каков наилучший способ сделать это? Я бы предпочел декларативное решение процессуальному.

Ответы [ 10 ]

56 голосов
/ 22 сентября 2009

Сначала преобразуйте ButtonField или CommandField в TemplateField, затем свяжите свойство кнопки 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;
}

Преимущество здесь в том, что вы можете довольно легко протестировать метод IsOverAgeLimit.

12 голосов
/ 22 сентября 2009

это может быть сделано, когда событие 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;
        }
    }
}

В демонстрационной версии кнопка «Изменить» не является Видимой (разметка HTML не отправляется клиенту) в тех строках, где возраст Клиента равен 30 *.

10 голосов
/ 28 марта 2014

Позвольте мне поделиться своим подходом к тому, что он стоит. Для меня преобразование командного поля в элемент управления полем шаблона не вариант, так как командное поле поставляется со встроенной функциональностью, которую в противном случае мне пришлось бы создавать самостоятельно, например, тот факт, что при нажатии «Изменить» оно изменяется на «Обновить», что при нажатии кнопки «Изменить» все ячейки в строке, которые являются метками, становятся текстовыми полями и т. д.

В моем подходе вы можете оставить командное поле как есть, затем вы можете при необходимости скрыть его с помощью кода. В этом примере я скрываю его, если в поле «Сценарий» сетки отображается текст «Факт» для соответствующей строки события 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;
            }
    }}
6 голосов
/ 12 декабря 2012

Скрыть весь столбец GridView

Если вы хотите полностью удалить столбец (т. Е. Не только кнопку) из таблицы, то используйте подходящий обработчик событий, например, для события OnDataBound, а затем скрыть соответствующий столбец на цели GridView. Выберите событие, которое сработает только один раз для этого элемента управления, т.е. не 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
    }
}
1 голос
/ 02 сентября 2018
<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>

Используйте этот код, чтобы отключить кнопку удаления в виде сетки из кода позади.

protected void gv_Document_RowDataBound(object sender, GridViewRowEventArgs e)
{ 
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        ((LinkButton)e.Row.Cells[7].Controls[0]).Visible = false;            
    }
}
1 голос
/ 03 декабря 2013

Чтобы условно контролировать представление полей Template / Command, используйте событие RowDataBound Gridview, например:

    <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;
        }
    }
1 голос
/ 11 мая 2011

Преобразовать CommandField в TemplateField и установить свойство visible кнопки на основе значения поля (true / false)

<asp:Button ID="btnSelect" 
runat="server" Text="Select" 
Visible='<%# DataBinder.Eval(Container.DataItem,"IsLeaf") %>'/>
0 голосов
/ 06 апреля 2017

Я сделал очень простую вещь, чтобы включить или отключить командную кнопку. Ниже моя сетка

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

        }
    }
0 голосов
/ 07 июля 2016

Вы можете скрыть CommandField или ButtonField на основе позиции (индекса) в GridView.

Например, если ваш CommandField находится на первой позиции (индекс = 0), вы можете скрыть его, добавив следующий код в событие RowDataBound 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;
    }
}
0 голосов
/ 22 сентября 2009

Если бы это основывалось на ролях, вы могли бы использовать панель множественного просмотра, но не уверены, что вы могли бы сделать то же самое для свойства записи.

Однако вы можете сделать это с помощью кода. В событии, связанном с строкой, вы можете скрыть или показать кнопку в нем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...