顯示具有 動態隱藏 標籤的文章。 顯示所有文章
顯示具有 動態隱藏 標籤的文章。 顯示所有文章

2025年2月13日 星期四

[研究][ASP.NET]GridView如何動態隱藏 BoundField 或 TemplateField 欄位不顯示?

[研究][ASP.NET]GridView如何動態隱藏 BoundField 或 TemplateField 欄位不顯示?

2025-02-12

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C#

(舊文翻出,不太記得是否測過)

********************************************************************************

範例1:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // 根據欄位名稱尋找欄位控制項
        BoundField field = GridView1.Columns.Cast<DataControlField>().Where(f => f.HeaderText == "ColumnName").OfType<BoundField>().FirstOrDefault();
        if (field == null)
        {
            TemplateField tempField = GridView1.Columns.Cast<DataControlField>().Where(f => f.HeaderText == "ColumnName").OfType<TemplateField>().FirstOrDefault();
            if (tempField != null)
            {
                // 如果是 TemplateField,尋找其內部的控制項
                Label label = e.Row.FindControl("Label1") as Label;
                if (label != null)
                {
                    // 隱藏控制項
                    label.Visible = false;
                }
            }
        }
        else
        {
            // 如果是 BoundField,尋找其對應的 TableCell
            TableCell cell = e.Row.Cells[GridView1.Columns.IndexOf(field)];
            if (cell != null)
            {
                // 隱藏 TableCell
                cell.Visible = false;
            }
        }
    }
}

在這個範例中,我們使用 Cast 方法將 GridView 的 Columns 屬性轉換為 DataControlField 集合,然後使用 Where 方法根據欄位名稱找到對應的欄位控制項。最後,我們使用 OfType 方法將 BoundField 或 TemplateField 強制轉換成對應的類型,並使用 FindControl 方法尋找內部控制項。如果是 BoundField,則需要使用 Cells 屬性尋找對應的 TableCell。

如果是 DetailsView 控制項,可以在 DataBound 事件中使用相同的方式尋找欄位控制項並隱藏它們。

********************************************************************************

範例2:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // 尋找欄位控制項
        BoundField field = GridView1.Columns[0] as BoundField;
        if (field == null)
        {
            TemplateField tempField = GridView1.Columns[0] as TemplateField;
            if (tempField != null)
            {
                // 如果是 TemplateField,尋找其內部的控制項
                Label label = e.Row.FindControl("Label1") as Label;
                if (label != null)
                {
                    // 隱藏控制項
                    label.Visible = false;
                }
            }
        }
        else
        {
            // 如果是 BoundField,尋找其對應的 TableCell
            TableCell cell = e.Row.Cells[0];
            if (cell != null)
            {
                // 隱藏 TableCell
                cell.Visible = false;
            }
        }
    }
}

在這個範例中,我們首先檢查欄位是否為 BoundField 或 TemplateField,並使用 FindControl 方法尋找對應的控制項。如果是 TemplateField,則需要尋找其內部的控制項。最後,我們設定控制項或 TableCell 的 Visible 屬性為 false,以隱藏欄位。注意在 DetailsView 控制項中,欄位控制項需要使用 Fields 屬性來尋找,而資料列控制項需要使用 Rows 屬性來尋找。

********************************************************************************

按下 Button 後,如何讓 GridView動態隱藏 BoundField 或 TemplateField 欄位不顯示?

若您使用 ASP.NET Web Forms,您可以在按下 Button 的事件處理程式中,設定 GridView 的相應 BoundField 或 TemplateField 的 Visible 屬性為 false,以隱藏該欄位。

以下是一個示範程式碼,假設您有一個 GridView 控制項名為 "GridView1",其中包含一個 BoundField 名為 "CustomerName":

範例3:

protected void Button1_Click(object sender, EventArgs e)
{
    GridView1.Columns[0].Visible = false; // 隱藏第一個欄位
}

若您要隱藏的欄位是一個 TemplateField,您可以指定該欄位的 Index 以隱藏:

範例4:

protected void Button1_Click(object sender, EventArgs e)
{
    GridView1.Columns[1].Visible = false; // 隱藏第二個欄位
}

請注意,這個示範程式碼中的 Index 值是從 0 開始算起的,所以第一個欄位的 Index 為 0,第二個欄位的 Index 為 1,以此類推。

********************************************************************************

能根據 BoundField 的 DataField,或 TemplateField 某屬性值,進行隱藏 ?

是的,您可以使用 BoundField 或 TemplateField 的 DataField 或某些屬性值來識別要隱藏的欄位,然後將 Visible 屬性設定為 false。

下面是一個示範程式碼,其中假設您有一個 GridView 控制項名稱為 "GridView1",其中包含一個 BoundField 名稱為 "CustomerName",您可以使用 BoundField 的 DataField 屬性來找到要隱藏的欄位:

範例5:

protected void Button1_Click(object sender, EventArgs e)
{
    // 找到名稱為 "CustomerName" 的 BoundField
    BoundField field = GridView1.Columns.OfType<BoundField>().FirstOrDefault(f => f.DataField == "CustomerName");
    if (field != null)
    {
        field.Visible = false; // 隱藏該欄位
    }
}

如果您要隱藏的是一個 TemplateField,則可以根據您在其屬性中使用的值來找到該欄位。例如,假設您的 TemplateField 包含一個 Label 控制項,其 ID 為 "CustomerNameLabel",您可以使用 TemplateField 的 HeaderTemplate 或 ItemTemplate 屬性來找到該 Label 控制項,然後將它隱藏:

範例6:

protected void Button1_Click(object sender, EventArgs e)
{
    // 找到包含 ID 為 "CustomerNameLabel" 的 Label 控制項的 TemplateField
    TemplateField field = GridView1.Columns.OfType<TemplateField>().FirstOrDefault(f => 
    {
        Label label = f.HeaderTemplate?.FindControl("CustomerNameLabel") as Label 
            ?? f.ItemTemplate?.FindControl("CustomerNameLabel") as Label;
        return label != null;
    });
    
    if (field != null)
    {
        field.Visible = false; // 隱藏該欄位
    }
}

在這個示範程式碼中,我們在 HeaderTemplate 和 ItemTemplate 中查找 ID 為 "CustomerNameLabel" 的 Label 控制項,並使用合併運算子 (??) 指定如果找不到 Label 控制項,則返回 null。如果找到了 Label 控制項,我們就可以得到包含它的 TemplateField,然後將其 Visible 屬性設定為 false。

(完)

相關

[研究][ASP.NET]DetailsView 如何動態隱藏 BoundField 或 TemplateField 欄位不顯示?

[研究][ASP.NET]DetailsView 如何動態隱藏 BoundField 或 TemplateField 欄位不顯示?

2025-02-12

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C#

(舊文翻出,不太記得是否測過)

********************************************************************************

(下圖)沒做任何隱藏前



Default.aspx:


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />&nbsp;
        <asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" style="height: 21px" />
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>" 
            DeleteCommand="DELETE FROM [Table4] WHERE [SN] = @SN" 
            InsertCommand="INSERT INTO [Table4] ([BookName], [BookIntro], [BookPrice]) VALUES (@BookName, @BookIntro, @BookPrice)" 
            SelectCommand="SELECT * FROM [Table4]" 
            UpdateCommand="UPDATE [Table4] SET [BookName] = @BookName, [BookIntro] = @BookIntro, [BookPrice] = @BookPrice WHERE [SN] = @SN">
            <DeleteParameters>
                <asp:Parameter Name="SN" Type="Int32" />
            </DeleteParameters>
            <InsertParameters>
                <asp:Parameter Name="BookName" Type="String" />
                <asp:Parameter Name="BookIntro" Type="String" />
                <asp:Parameter Name="BookPrice" Type="Int32" />
            </InsertParameters>
            <UpdateParameters>
                <asp:Parameter Name="BookName" Type="String" />
                <asp:Parameter Name="BookIntro" Type="String" />
                <asp:Parameter Name="BookPrice" Type="Int32" />
                <asp:Parameter Name="SN" Type="Int32" />
            </UpdateParameters>
        </asp:SqlDataSource>
        <asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px" AllowPaging="True" 
             DefaultMode="Insert"
            AutoGenerateRows="False" DataKeyNames="SN" DataSourceID="SqlDataSource1" OnDataBound="DetailsView1_DataBound">
            <Fields>
                <asp:BoundField DataField="SN" HeaderText="SN" InsertVisible="False" ReadOnly="True" SortExpression="SN" />
                <asp:BoundField DataField="BookName" HeaderText="書名" SortExpression="BookName" />
                <asp:BoundField DataField="BookIntro" HeaderText="簡介" SortExpression="BookIntro" />
                <asp:TemplateField HeaderText="價格" SortExpression="BookPrice">
                    <EditItemTemplate>
                        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("BookPrice") %>'></asp:TextBox>
                    </EditItemTemplate>
                    <InsertItemTemplate>
                        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("BookPrice") %>'></asp:TextBox>
                        <asp:Label ID="Label_BookPrice" runat="server">註解</asp:Label>
                    </InsertItemTemplate>
                    <ItemTemplate>
                        <asp:Label ID="Label1" runat="server" Text='<%# Bind("BookPrice") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" ShowInsertButton="True" />
            </Fields>
        </asp:DetailsView>
    </form>
</body>
</html>

Default.aspx.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        // 使用欄位索引編號來隱藏,程式較簡潔,但欄位增減後要改索引麻煩
        protected void Button1_Click(object sender, EventArgs e)
        {
            //DetailsView1.Fields[0].Visible = false; // SN
            //DetailsView1.Fields[1].Visible = false; // BookName
            DetailsView1.Fields[2].Visible = false; // BoundField,BookIntro
            DetailsView1.Fields[3].Visible = false; // TemplateField,BookPrice
        }

        // BoundField 使用欄位資料名稱 (DataField) 來隱藏欄位
        // TemplateField 使用欄位顯示名稱 (HeaderText) 來隱藏欄位
        // 程式較麻煩,欄位增減維護較方便
        protected void Button2_Click(object sender, EventArgs e)
        {
            foreach (DataControlField field in DetailsView1.Fields)
            {
                if (field is BoundField)
                {
                    BoundField boundField = field as BoundField;
                    if (boundField.DataField == "BookIntro")
                    {
                        boundField.Visible = false;
                    }
                }
                else if (field is TemplateField)
                {
                    TemplateField templateField = field as TemplateField;
                    if (templateField.HeaderText == "價格")
                    {
                        templateField.Visible = false;
                    }
                }
            }
            DetailsView1.DataBind();
        }

        // 直接寫在 DataBound() 的方法
        protected void DetailsView1_DataBound(object sender, EventArgs e)
        {

            //error CS0030: 無法將類型 'System.Web.UI.Control' 轉換成 'System.Web.UI.WebControls.BoundField'
            //BoundField bf = (BoundField)DetailsView1.FindControl("BookIntro");
            BoundField bf = DetailsView1.Fields.OfType<BoundField>().FirstOrDefault(f => f.DataField == "BookIntro");

            //error CS0030: 無法將類型 'System.Web.UI.Control' 轉換成 'System.Web.UI.WebControls.TemplateField'
            //TemplateField tf = (TemplateField)DetailsView1.FindControl("BookPrice");
            TemplateField tf = (TemplateField)DetailsView1.Fields.Cast<DataControlField>().FirstOrDefault(f => f.HeaderText == "價格");

            // 根據控制項的型別設定 Visible 屬性
            if (bf != null)
            {
                bf.Visible = false;
            }
            if (tf != null)
            {
                tf.Visible = false;
            }
        }
        //---
        // 進階到控制 Cell
        /*
        protected void DetailsView1_DataBound(object sender, EventArgs e)
        {
            // 尋找欄位控制項
            BoundField field = DetailsView1.Fields[2] as BoundField;
            if (field == null)
            {
                TemplateField tempField = DetailsView1.Fields[2] as TemplateField;
                if (tempField != null)
                {
                    // 如果是 TemplateField,尋找其內部的控制項
                    Label label = DetailsView1.FindControl("簡介") as Label;
                    if (label != null)
                    {
                        // 隱藏控制項
                        label.Visible = false;
                    }
                }
            }
            else
            {
                // 如果是 BoundField,尋找其對應的 TableCell

                TableCell cell0 = DetailsView1.Rows[2].Cells[0]; //欄位名稱,一但隱藏,欄位值會偏移到欄位名稱位置
                TableCell cell1 = DetailsView1.Rows[2].Cells[1]; //欄位值
                if (cell0 != null)
                {
                    // 隱藏 TableCell
                    cell1.Visible = false;
                }
            }
            //---
            TemplateField tempField3 = DetailsView1.Fields[3] as TemplateField;
            if (tempField3 != null)
            {
                // 如果是 TemplateField,尋找其內部的控制項
                Label label = (Label)DetailsView1.FindControl("Label_BookPrice");
                if (label != null)
                {
                    // 隱藏控制項
                    label.Visible = false;
                }
            }
        }
        */
        //---
    }
}

(完)

相關