web-dev-qa-db-ja.com

GridviewでCommandFieldまたはButtonFieldを条件付きで非表示にします

個人レコードを表示するGridViewがあります。基になるレコードのプロパティに基づいて、CommandFieldまたはButtonFieldを条件付きで表示したい。アイデアは、特定の人に対してのみコマンドを実行できるようにすることです。

これを行う最良の方法は何ですか?手続き型よりも宣言型のソリューションが望ましいです。

26
Larsenal

まず、ButtonFieldまたはCommandFieldTemplateFieldに変換してから、ボタンの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メソッドをかなり簡単にテストできることです。

57
ViNull

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

デモページはこちら

markup

<%@ 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歳である行では、編集ボタンはVisibleではありません(HTMLマークアップはクライアントに送信されません)。

12
Russ Cam

価値のあるアプローチを共有してください。コマンドフィールドにはテンプレートフィールドコントロールへの変換はオプションではありません。コマンドフィールドには組み込みの機能が付属しているためです。 [編集]をクリックすると、ラベルである行のすべてのセルがテキストボックスなどになること.

私のアプローチでは、コマンドフィールドをそのままにして、必要に応じてコードビハインドで非表示にできます。この例では、グリッドのフィールド「シナリオ」に、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;
            }
    }}
10
leoinlios

GridView列全体を非表示にする

テーブルから列(ボタンだけでなく)を完全に削除する場合は、適切なイベントハンドラーを使用します。 OnDataBoundイベントの場合、ターゲットGridViewの適切な列を非表示にします。このコントロールに対して1回だけ発生するイベント、つまり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
    }
}
6
Scotty.NET
<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>

このコードを使用して、コードビハインドからgridviewの削除ボタンを無効にします。

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
Bhavin

CommandFieldをTemplateFieldに変換し、フィールドの値に基づいてボタンの表示プロパティを設定します(true/false)

<asp:Button ID="btnSelect" 
runat="server" Text="Select" 
Visible='<%# DataBinder.Eval(Container.DataItem,"IsLeaf") %>'/>
1
Rory

テンプレート/コマンドフィールドのビューを条件付きで制御するには、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;
        }
    }
1
Altaf Patel

コマンドボタンを有効または無効にするために、非常に簡単なことをしました。以下は私のグリッドです

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

これがロールに基づいている場合、マルチビューパネルを使用できますが、レコードのプロパティに対して同じことができるかどうかはわかりません。

ただし、コードを使用してこれを行うことができます。 rowdataboundイベントでは、ボタンを非表示または表示できます。

0
klabranche

GridViewの位置(インデックス)に基づいてCommandFieldまたはButtonFieldを非表示にできます。

たとえば、CommandFieldが最初の位置(インデックス= 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;
    }
}
0
Wilson