作者:donna donna.zdn@gmail.com 自由轉載 但請保留作者資訊
關於IE WebControls,也許您早就知道了吧,它不僅小巧而且開源,您可以從中學到.net控制項開發的一些技巧。最近在用它的Toolbar控制項來實現一些工具條,嗯,用起來很簡單,效果也不錯(尤其是在IE裡,不加任何修飾就可以實現象WinForm上的工具,不愧是微軟開發的)。但是有個缺點就是不支援用戶端事件,比如我有個“刪除”按鈕,想在使用者點擊後確認是否刪除,如果確認則提交到伺服器執行刪除操作,否則不提交。結果翻遍了Toolbar的所有屬性、方法也沒有找到如何設定讓某個按鈕調用特定的用戶端指令碼。既然它是開源的,那就自己實現個方法吧!
我的想法是為Toolbar的Button提供一個屬性,通過設定該屬性為一個用戶端指令碼的方法的名稱來實現指令碼的調用,該方法返回一個布爾值,如果為true則提交到伺服器,false則不提交。
實現步驟:
1、通過分析原始碼,ToolbarButton類是在ToolbarButton.cs檔案中實現的,因此ToolbarButton.cs添加ClientClickMethod屬性
/**//// <summary>
/// Client Method
/// </summary>
[DefaultValue("")]
[Category("Behavior")]
[ResDescription("Client Method")]
public string ClientClickMethod
{
get
{
object obj = ViewState["ClientClickMethod"];
return (obj == null) ? String.Empty : (string)obj;
}
set { ViewState["ClientClickMethod"] = value; }
}
2、修改WriteItemAttributes方法將屬性指定的方法對應到用戶端控制項的onclick方法上
protected override void WriteItemAttributes(HtmlTextWriter writer)
{
base.WriteItemAttributes(writer);
string style = HoverStyle.CssText;
if (style != String.Empty)
{
writer.WriteAttribute("hoverstyle", style);
}
style = SelectedStyle.CssText;
if (style != String.Empty)
{
writer.WriteAttribute("selectedstyle", style);
}
writer.WriteAttribute("onkeydown", "if (event.keyCode==13){event.returnValue=false}");
//add by donna,2006-08-02
if (ClientClickMethod != String.Empty)
{
writer.WriteAttribute("onclick","try{event.srcElement._IsCanceled=!" + ClientClickMethod +"}catch(e){event.srcElement._IsCanceled=true;}");
}
//add end
}
您也許會問,為什麼不用類似onclick="return confirm('Message');"的方法來實現呢?原因為是IE在顯示有Toolbar的頁面時是調用toolbar.htc中的指令碼來產生Toolbar的(這也就是為什麼安裝IE WebControls時要把Runtime目錄下的內容複寫到Web網站根目錄下的webctrl_client\1_0目錄下的原因),而它的__doPostBack方法是在整個Toolbar上調用,而不是某個ToolButton上調用的,雖然在ToolButton上return false了但不能阻止其PostBack,因此這裡採用了一種變通的方法,先在ToolButton的onclick中設定一個標誌即event.srcElement._IsCanceled,然後在PostBack之前檢查這個標誌,如果為true則不提交。
3、修改toolbar.htc指令碼
function f_OnClick()
{
if (_IsSubmitting || !_Ready)
return;
//add by donna 2006-08-02;用來在IE中判斷是否可以提交
if (event.srcElement.getAttribute("_IsCanceled"))
return;
//add end
var oCell = f_FindSurroundingCell(event.srcElement);
if ((oCell != null) && (!oCell.isDisabled))
f_SelectItem(oCell);
_KeyboardClick = false;
}
4、可有可無,修改runtime檔案的路徑
如果您不希望把Runtime目錄下的內容複寫到Web網站根目錄下的webctrl_client\1_0目錄中,您只要改一下BaseRichControl.cs檔案的AddPathToFilename函數就行,這裡把它改到了虛擬目錄的webctrl_client\1_0目錄中
internal static string AddPathToFilename(HttpContext context, string filename)
{
//modified by donna,2006-8-2
return context.Request.ApplicationPath + "/webctrl_client/1_0/" + filename;
//modify end
//return FindCommonPath(context) + filename;
}
現在可以試試效果了,結果發現在IE中一切正常,在Firefox中完全沒有效果,對比IE和Firefox產生的HTML代碼發現asp.net對他們的實現機制不一樣(具體也不太清楚,知道的朋友可以說說)。
5、支援Firefox
修改ToolbarButton.cs檔案AddAnchorAttributes方法
//modified by donna,2006-8-8;用來支援FireFox
if (ClientClickMethod != String.Empty)
{
writer.AddAttribute(HtmlTextWriterAttribute.Href, "javascript:if (" + ClientClickMethod.Replace(";","") + "){" + AnchorHref + ";}");
}
else
{
writer.AddAttribute(HtmlTextWriterAttribute.Href, "javascript:" + AnchorHref);
}
//modify end
使用方法:
1、運行build.bat編譯控制項;
2、將src\runtime\目錄下所有內容複寫到你的WEB應用程式目錄的webctrl_client\1_0\目錄下;
3、請參考示範程式使用。
環境:WIN2003、IIS6、VS2003、Framework1.1、IE6、FireFox1.5
代碼下載
donna.zdn@gmail.com