[ASP.net WebForm] 解決放在BlockUI裡的UpdatePanel失效,沒有反應
之前工作上遇到這樣的情形,因為要在BlockUI裡做連動下拉選單
但BlockUI跳出來的區域其實是原本網頁畫面裡的div,DropDownList若PostBack的話,整個畫面會刷新把div洗掉
所以很直覺地用UpdatePanel去包住那些下拉選單做無刷新的效果
但這樣又會產生另一個問題:
裡頭的下拉選單不管怎麼拉,第二層選單資料都沒出來
	
Sample Code:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Register TagPrefix="include" TagName="ddlEmployee" Src="~/include/wucddlEmployee.ascx" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <%--引用jQuery核心函式庫--%>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <%--引用blockUI函式庫--%>
    <script src="Scripts/jquery.blockUI.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(init);
        function init() {
            $("#showDiv").click(function () {
                $.blockUI({ message: $('#block') });
            });
            $('#closeUI').click(function () {
                $.unblockUI();
                return false;
            });
        }
     
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager runat="server" />
     
    
    <input id="showDiv" type="button" value="顯示隱藏的div" />
    <!--↓blockUI要顯示的div-->
    <div style="cursor: default; display: none;" id="block">
    <!--裡頭再包一層UpdatePanel-->
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <!--WebUserControl的連動下拉選單,詳細做法可參考喵大的文章:http://www.dotblogs.com.tw/topcat/archive/2008/06/06/4247.aspx-->
            <include:ddlEmployee ID="ddlEmployee1" runat="server" />
            <include:ddlEmployee ID="ddlEmployee2" runat="server" />
            <include:ddlEmployee ID="ddlEmployee3" runat="server" />
        </ContentTemplate>
    </asp:UpdatePanel>
        <a style="float: right;" id="closeUI" href="#close">關閉</a>
    </div>
    </form>
</body>
</html>
解決辦法:
打開blockUI核心函式庫檔案jquery.blockUI.js,修改裡頭的程式碼
找到這行
var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
body換成form
	var layers = [lyr1,lyr2,lyr3], $par = full ? $('form') : $(el);
	 
再找到這行
	els = $('body').children().filter('.blockUI').add('body > .blockUI');
	
	一樣body換成form
els = $('form').children().filter('.blockUI').add('form > .blockUI');
修改完存檔後,再執行一次程式,連動下拉選單就正常了
	
參考:JQuery BlockUI with UpdatePanel Viewstate Issue
2012.3.10晚上 追記該員工資料連動下拉選單的寫法
先宣告介面
using System;
using System.Collections.Generic;
using System.Web;
 
public interface IOrder    
{
     void notifyChange(string id);
}
 
public interface  IPublisher  
{
    //加入訂閱者
     void addOrder(IOrder order);
}
 
  
準備一個WebUserControl當做一個DropDownList
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="wucddlEmployee.ascx.cs" Inherits="include_wucddlEmployee" %>
<asp:DropDownList ID="ddlEmployee" runat="server" AutoPostBack="True" 
    DataSourceID="sdsEmployeeID" DataTextField="EmployeeName"   
    DataValueField="EmployeeID" 
    onselectedindexchanged="ddlEmployee_SelectedIndexChanged">
</asp:DropDownList>
<asp:SqlDataSource ID="sdsEmployeeID" runat="server" 
    ConnectionString="<%$ ConnectionStrings:NWind %>"  
    SelectCommand="Select '-1' As EmployeeID,N'請選擇' As EmployeeName
                   Union All
                   SELECT EmployeeID, EmployeeName
                   FROM Employees 
                   Where (@EmployeeID ='' Or ManagerID=@EmployeeID)
                   ORDER BY EmployeeID ASC">
                   <SelectParameters>
                       <asp:Parameter Name="EmployeeID" Type="String" ConvertEmptyStringToNull="false"   DefaultValue=""   />
                   </SelectParameters>
</asp:SqlDataSource>
WebUserControl的Code-Behind
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class include_wucddlEmployee : System.Web.UI.UserControl,IPublisher,IOrder
{
    //此發行者擁有的訂閱者
    List<IOrder> myOrders = new List<IOrder>();
    //加入訂閱者
    public void addOrder(IOrder order)
    {
        this.myOrders.Add(order);
    }
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    protected void ddlEmployee_SelectedIndexChanged(object sender, EventArgs e)
    {
        foreach (IOrder order in this.myOrders)
	    {
            string EmployeeID = this.ddlEmployee.SelectedValue;
            order.notifyChange(EmployeeID);
	    }
         
    }
    public void notifyChange(string id)
    {
        this.sdsEmployeeID.SelectParameters["EmployeeID"].DefaultValue = id;
    }
}
最後把WebUserControl拉到Default.aspx畫面上
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Register TagPrefix="include" TagName="ddlEmployee" Src="~/include/wucddlEmployee.ascx" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <%--引用jQuery核心函式庫--%>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <%--引用blockUI函式庫--%>
    <script src="Scripts/jquery.blockUI.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(init);
        function init() {
            $("#showDiv").click(function () {
                $.blockUI({ message: $('#block') });
            });
            $('#closeUI').click(function () {
                $.unblockUI();
                return false;
            });
        }
     
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager runat="server" />
         
    <input id="showDiv" type="button" value="顯示隱藏的div" />
    <div style="cursor: default; display: none;" id="block">
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <include:ddlEmployee ID="ddlEmployee1" runat="server" />
            <include:ddlEmployee ID="ddlEmployee2" runat="server" />
            <include:ddlEmployee ID="ddlEmployee3" runat="server" />
        </ContentTemplate>
    </asp:UpdatePanel>
        <a style="float: right;" id="closeUI" href="#close">關閉</a>
    </div>
    </form>
</body>
</html>