KB-MasterPage ClientID Search Enhancement

先前曾提出在MasterPage中解決ClientID被加料的方法,最近發現原來的做法有些小缺點。

原先的邏輯只額外多搜尋ContentPlaceHolder的字頭(Prefix),但是若其中有UserControl,則UserControl的ClientID還會被加上UserControl的ID。例如: (UC11中只有一個TextBox1)

<asp:Content ID="Content2" ContentPlaceHolderID="Editor" Runat="Server">
    <uc1:UC1 ID="UC11" runat="server" />
</asp:Content>

實際的TextBox1的ClientID會變成ctl00_Editor_UC11_TextBox1,原先的做法只會Search到ctl00_Editor_TextBox1,因此UserControl下的物件就變成化外之民。

<input name="ctl00$Editor$UC11$TextBox1" type="text" id="ctl00_Editor_UC11_TextBox1" />

我修改了原有的程式,將UserControl的ClientID也加入要搜索的字頭之一,同時對ContentPlaceHolder下的Control也要逐一巡迴檢查,這樣就能把UserControl下的物件納入afa_mpget的查找範圍內。

    public static void searchContentPlaceHolder(Control ctrl, List<string> lst)
    {
        if (ctrl is ContentPlaceHolder || ctrl is UserControl)
            lst.Add(ctrl.ClientID);
        if (ctrl.HasControls())
        {
            foreach (Control c in ctrl.Controls)
                searchContentPlaceHolder(c, lst);
        }
    }

只是,原先與網友大估討論過將邏輯放在Page_Init解決對ViewState干擾的做法,由於在搜尋的時候必須確認網頁上的Control物件都已Create妥當,以免在列舉時有遺珠,因此放在Page_Load()比較OK。最終決定的做法: 放在Page_Load()+Page.Header.Controls.Add(...)。

歡迎推文分享:
Published 19 January 2008 10:53 AM 由 Jeffrey
Filed under: ,
Views: 20,548



意見

# 大估 said on 21 January, 2008 12:59 AM

感謝黑暗大大~

又學到東西了~

# sam said on 20 February, 2009 01:15 AM

問下黑大~

我現在開發一個自訂控制項(server端)

當中有jQuery的callback來當作client的回呼事件

這個控制項在獨立的網頁上使用是正常無誤的~

但在Masterpage當中使用時,後端的callback機制卻無法

產生事件來~

能否麻煩黑大針對這個問題幫我想想法子先...

# Jeffrey said on 20 February, 2009 02:40 AM

to sam, "當中有jQuery的callback來當作client的回呼事件... 後端的callback機制卻無法產生事件來...  ",看不是很懂,看要不要把關鍵部分的Code貼出來,大家再幫忙研究。

# sam said on 20 February, 2009 03:13 AM

Me.Page.ClientScript.GetCallbackEventReference(Me, "'" & Item.Key & "'", Item.ClientCallBack, "''") & ";"

上面這段是我在自訂控制項裡所寫的callback產生語法

當然我也先實作了這個控制項的 ICallbackEventHandler

ME <---就是我的自訂控制項本身來源

下方是產生後的Jquery script

<script type="text/javascript">

//<![CDATA[

WebForm_InitCallback();$(document).ready(function() {

$('#ctl00_ContentPlaceHolder1_Label1').contextMenu('ctl00_ContentPlaceHolder1_TM',{

bindings: {

'Excel': function(t) {

WebForm_DoCallback('ctl00_ContentPlaceHolder1_TM','Excel',ReceiveServerData,'',null,false);

}

}

});

});

//]]>

</script>

在一般單一的Aspx網頁之中可以正常的run

但加諸在masterpage就沒有辦法針對自訂控制項來進行

相關的click事件

搞不太懂,是不是因為包在masterpage當中的原因...

試了很多種方法,它還是沒有辦法將click事件傳回到server... 煩人的masterpage~~~

# Jeffrey said on 23 February, 2009 01:43 PM

to sam, 由你描述的情境,我懷疑是因為套用Materpage後ClientId不同造成的,建議你檢視套用MasterPage時的HTML原始碼,看看ctl00_ContentPlaceHolder1_Label1、ctl00_ContentPlaceHolder1_TM這些ID是否已改變了。

# sam said on 24 February, 2009 01:15 AM

to Jeffrey

我也想過這問題,是不是因為控制項在其底層所造成~

但事實或許不然哦...

因為雖然被改變其ID但,我可以在後端自由改變其ID

覺得是出在開發的控制項當中~不知怎配合Masterpage

來套用配合,因為我不單單是在單一網頁配合Masterpage

是還有一層的自訂控制項元件在網頁當中使用...

有點就 Masterpage--->aspx--->自訂控制項

單一網頁的問題我會處理,但裡頭加了自訂控制項後,事件就

無法觸發...-,- 快瘋囉=.=

# sam said on 26 February, 2009 05:57 PM

有沒有大大在開發自訂控制項時,有遇過類似的問題呢?

簡單來說

1.在單一的表單裡引用自訂控制項,所有的callback事件都得以正常觸發與使用

2,在masterpage的模式套用底下,jquery的語法可以正常觸發,但server端的事件卻無法觸發呢?

我真的想破頭了... 也隨意配合masterpage產生html時的加料名(動態在自訂控制項裡將Render方法裡修正ID),但這是javascrip的影響而已,並不是隨著後端的事件而影響,這實在是很麻煩,搞不懂為何在Masterpage的套用底下,自訂控制項的事件無法得以觸發呢....=.="'

倘若有大大有這方面的開發經驗,再分享出來...萬分感謝...

# Jeffrey said on 26 February, 2009 07:08 PM

to sam, 我覺得"動態在自訂控制項裡將Render方法裡修正ID"跟"server端的事件卻無法觸發"有關,UserControl裡的ClientID加料為的是要跟Server端相呼應,在Render更動ClientID,可能會導致Server端的機制失效。

# sam said on 26 February, 2009 07:44 PM

to : Jeffrey

動態異動僅為了測試masterpage的原故

實際上我是用這個控制項本身的id為條件(me.clientid)

在Render方法裡是為了配合輸出jquery的html 如下:

WebForm_InitCallback();$(document).ready(function() {

$('#ctl00_ContentPlaceHolder1_Label1').contextMenu('ctl00_ContentPlaceHolder1_TM',{

bindings: {

'Excel': function(t) {

WebForm_DoCallback('ctl00_ContentPlaceHolder1_TM','Excel',ReceiveServerData,'',null,false);

ctl00_ContentPlaceHolder1_TM <---就是本身控制項的id

但如果在單一網頁之中就變成

WebForm_InitCallback();$(document).ready(function() {

$('#Label1').contextMenu('TM',{

bindings: {

'Excel': function(t) {

WebForm_DoCallback('TM','Excel',ReceiveServerData,'',null,false);

TM<------單一網頁的名稱

就很正常的RUN...

# Jeffrey said on 27 February, 2009 03:19 AM

to sam, 原來我誤解你的意思,你變更的是呼叫時配合MasterPage使用加料版的ClientId,而不是去控制ClientId。這樣子看起來,程式應該會正常運作才對,我沒什麼點子。如果可行,看要不要把會出錯的網頁提取成可執行的小Web Application,讓大家幫你深入研究看看。

# Sam said on 03 March, 2009 11:51 PM

to Jeffrey 大大~~~

www.dotblogs.com.tw/.../5876.aspx

以上的網址是我寫自訂控制項的靈感來源

這個網站將jquery寫成幾則很不錯的自訂控制項

當中的右鍵選單也就是我提出的問題來源集

放置一般單一網頁可以正常的Run

但老話重提,一旦以Masterpage的模式就躺了....

目前公司著重這方面的方案,倘若可行...勢必可以增加

小弟的產能...........但卡關卡粉久了~~~

若可以,希望j大能一起實作且試著看看這問題先~

# Jeffrey said on 04 March, 2009 09:00 AM

to sam, 試了一下,我想你的問題出在

'Excel': function(t) { WebForm_DoCallback(...

這裡的'Excel'應該也要對應到己加料的ClientId才對。我試改了TBContextMenu.vb Render(), 先算出加料的前置語法:

Dim sPrefix As String

sPrefix = Me.ClientID.Substring(0, Me.ClientID.Length - Me.ID.Length)

在產生bindings對應時加上:

oScript.AppendLine("'" & sPrefix & oItem.Key & "': function(t) {")

試了一下,這樣子在MasterPage下就可以動了。

# sam said on 05 March, 2009 12:13 AM

TO Jeffery :    j 大大...您真是一語驚醒夢中人!!

我只顧著會異動的元件名稱,沒想到那個被點選的物件也會

隨著變化clientID....

好在佳有您幫我看穿這問題...這問題困擾我很久了!!

再次強力的感謝您的指導! 謝謝...謝謝! ^.^

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<January 2008>
SunMonTueWedThuFriSat
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789
 
RSS
創用 CC 授權條款
【廣告】
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication