[ASP.NET][WebForm]從Main Page傳遞方法給User Control執行

同事的專案寫了一個控制Gridview每頁顯示幾筆的Custom Control(user control)。但同事初始設計時,Custom Control內容只有一個下拉選單DropDownList,沒有把她和gridview結合在一起;後面開始大量開發表單時也沒特別在分頁筆數控制項加上Postback時對應控制Main page Gridview更新的方法,因此當user選擇新的筆數選項後,Gridview內容不會同步更新,使用者操作有點不順手,被開單告發了,來前線救援。

 

希望網頁的效果:從每頁2筆選取每頁6筆後(custom control),直接更新gridview(main page)

 

功能示意圖

這一題我們可以用事件將方法作為參數傳遞!

作法是將Main Page重新載入Gridview的方法(PageSizeChanged)傳遞給Custom  Control的事件,user在custom control修改每頁顯示幾筆時,再從委派給選取項目變更事件的方法中(ddlPageSize_SelectedIndexChanged),執行剛剛Main Page註冊進來的方法(PageSizeChanged)

 


1.建立Custom Control(Pager.ascx)

首先建立一個名稱為Pager.ascx且內含DropDownList控制項的user control,並且透過intellisense( CTRL+J)建立SelectedIndexChanged方法。

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Pager.ascx.cs" Inherits="MonoWebForm.usercontrol.Pager" %>
<asp:DropDownList ID="ddlPageSize" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlPageSize_SelectedIndexChanged">
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>4</asp:ListItem>
<asp:ListItem>6</asp:ListItem>
<asp:ListItem>8</asp:ListItem>
<asp:ListItem>10</asp:ListItem>
</asp:DropDownList>

 

按一下F7進入程式碼Pager.ascx.cs

  • 加一個屬性PageSize給Main Page使用
  • 宣告一個存取修飾詞是公開的事件,名稱為PageSizeChanged,準備接收Main Page傳進來的方法
  • 委派給選取項目變更事件的方法中(ddlPageSize_SelectedIndexChanged),執行Main Page傳進來的方法
using System;
namespace ForgotWebForm.usercontrol
{
    public partial class Pager : System.Web.UI.UserControl
    {
        public int PageSize
        {
            get { return int.Parse(this.ddlPageSize.SelectedValue); }
        }
        public event EventHandler PageSizeChanged;
        protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.PageSizeChanged?.Invoke(this, new EventArgs());
        }
    }
}

 


2.Main Page(Poker.aspx)

  • 引用Custom Control(Pager.ascx)
  • 建立gridview
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Poker.aspx.cs" Inherits="MonoWebForm.Poker" %>
<%@ Register Src="~/usercontrol/Pager.ascx" TagPrefix="uc1" TagName="Pager" %>

<!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">
        <div>
            <uc1:Pager id="uscPager" runat="server"/>
            <asp:GridView ID="gdvData" runat="server" CssClass="table table-hover table-bordered" 
                OnPageIndexChanging="gdvData_PageIndexChanging"
                AutoGenerateColumns="false" AllowPaging="true" Font-Names="lucida console">
                <Columns>
                    <asp:BoundField DataField="ID" HeaderText="編號#" />
                    <asp:BoundField DataField="NAME" HeaderText="人物名稱" />
                    <asp:BoundField DataField="TITLE" HeaderText="卡種" />
                    <asp:BoundField DataField="COLOR" HeaderText="花色" />
                </Columns>
            </asp:GridView>
        </div>
    </form>
</body>
</html>

 

按一下F7進入程式碼Poker.aspx.cs

  • 建立buildTestData方法
  • 建立loadGridData方法
  • 依序在Page_Load、PageIndexChanging及PageSizeChanged方法執行loadGridData方法來重新載資料
  • 在Page_Load方法內將PageSizeChanged方法註冊給Pager.ascx的PageSizeChanged事件
using System;
using System.Collections.Generic;

namespace ForgotWebForm
{
    public partial class Poker : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                loadGridData();
            }
            this.uscPager.PageSizeChanged += new EventHandler(PageSizeChanged);
        }
        private void loadGridData()
        {
            gdvData.PageSize = this.uscPager.PageSize;
            gdvData.DataSource = buildTestData();
            gdvData.DataBind();
        }
        protected void gdvData_PageIndexChanging(object sender, System.Web.UI.WebControls.GridViewPageEventArgs e)
        {
            gdvData.PageIndex = e.NewPageIndex;
            loadGridData();
        }
        public void PageSizeChanged(object sender, EventArgs e)
        {
            loadGridData();
        }
        public List<poker> buildTestData()
        {
            List<poker> pokers = new List<poker>();
            pokers.Add(new poker { Id = 1, Name = "David", Title = "King", Color = "Spades" });
            pokers.Add(new poker { Id = 2, Name = "Charlemagne", Title = "King", Color = "Hearts" });
            pokers.Add(new poker { Id = 3, Name = "Caesar", Title = "King", Color = "Diamonds" });
            pokers.Add(new poker { Id = 4, Name = "Alexander", Title = "King", Color = "Clubs" });

            pokers.Add(new poker { Id = 5, Name = "Athena", Title = "Queen", Color = "Spades" });
            pokers.Add(new poker { Id = 6, Name = "Judith", Title = "Queen", Color = "Hearts" });
            pokers.Add(new poker { Id = 7, Name = "Rachel", Title = "Queen", Color = "Diamonds" });
            pokers.Add(new poker { Id = 8, Name = "Argine", Title = "Queen", Color = "Clubs" });

            pokers.Add(new poker { Id = 9, Name = "Ogier", Title = "Jack", Color = "Spades" });
            pokers.Add(new poker { Id = 10, Name = "La Hire", Title = "Jack", Color = "Hearts" });
            pokers.Add(new poker { Id = 11, Name = "Hector", Title = "Jack", Color = "Diamonds" });
            pokers.Add(new poker { Id = 12, Name = "Hammer", Title = "Jack", Color = "Clubs" });
            return pokers;
        }
    }
}

 

呼~

 


參考

Calling a method in parent page from user control

https://stackoverflow.com/questions/623136/calling-a-method-in-parent-page-from-user-control

 

How do i raise an event in a usercontrol and catch it in mainpage?

https://stackoverflow.com/questions/6192739/how-do-i-raise-an-event-in-a-usercontrol-and-catch-it-in-mainpage