用JS通过动态加载UserControl的代码如下:
html部分:
<asp:ScriptManager runat="server">
<Services>
<asp:ServiceReference Path="~/ScriptService.asmx" />
</Services>
</asp:ScriptManager>
<input type="button" value="Load Customer Order" onclick="getData('~/Controls/GridView.ascx');" />
<input type="button" value="Load Login" onclick="getData('~/Controls/LoginControl.ascx');" />
<div id="testDiv"></div>
</form>
<script type="text/javascript">
///<summary>Method for Web Service Failed Event</summary>
///<param name="error">Error Object</param>
///<returns>false</returns>
function onFailedWS(error)
{
alert(error.get_message());
}
///<summary>This is the callback function that processes the Web Service return value.</summary>
///<param name="result">result Object from Web Service</param>
function SucceededCallback(result)
{
//get the div element
var RsltElem = $get("testDiv");
//update div inner Html
RsltElem.innerHTML =result;
//format table inside the div
//if you have multiple table call format table in loop
formatTable(RsltElem.getElementsByTagName('table')[0].id)
}
///<summary>This function calls the GetPriorityCodes Web Service method.</summary>
///<param name="error">Succeed Object</param>
///<param name="error">Error Object</param>
function getData(controlLocation)
{
ScriptService.GetControlHtml(controlLocation, SucceededCallback, onFailedWS);
}
function formatTable(gvID){
//get the gridview
var gv = $get(gvID);
//get numbers of column in grid view
cols = gv.rows[0].cells.length - 1;
//get numbers of rows in grid view
rows = gv.rows.length -1;
//intialized looping variables
var i=0;
var j=0;
//loop for each row in gridview
for(i=1;i<rows;i++){
//attach mouseover event for row
$addHandler(gv.rows[i], "mouseover", mouseOver);
//attach mouseout event for row
$addHandler(gv.rows[i], "mouseout", mouseOut);
//attach click event for row
$addHandler(gv.rows[i], "click", onClick);
//loop for each cell in row
for(j=0;j<cols;j++){
//set tooltip for cells in row
setTitle(gv.rows[i].cells[j]);
}
}
}
function setTitle(object){
//check browser type
if(Sys.Browser.name =="Firefox"){
object.title = object.textContent;
}
else{
object.title = object.innerText;
}
}
function mouseOver(objectEvent){
//is row already clicked
if(! isClickedStyleSet(objectEvent.target.parentNode.className))
{
//set class name
objectEvent.target.parentNode.className = "row-over" ;
//check browser type
if(Sys.Browser.name !="Firefox"){
objectEvent.target.parentNode.style.cursor ="hand";
}}
}
function mouseOut(objectEvent){
//is row already clicked
if(! isClickedStyleSet(objectEvent.target.parentNode.className)){
//set class name
objectEvent.target.parentNode.className = "data-row" ;
}}
function onClick(objectEvent){
//set class name
if(! isClickedStyleSet(objectEvent.target.parentNode.className))
{
objectEvent.target.parentNode.className = "row-select" ;
}
else
{
objectEvent.target.parentNode.className = "data-row" ;
}
}
function isClickedStyleSet(className){
//if row is already clicked return true
if(className == "row-select"){
return true;
}
return false;
}
</script>
WebService部分:
using System;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.Services;
using System.Web.Services.Protocols;
/// <summary>
/// Summary description for ScriptService
/// To access from ASP.NET AJAX remember to mentioned
/// System.Web.Script.Services.ScriptService() attribute
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService()]
public class ScriptService : System.Web.Services.WebService
{
public ScriptService()
{
//Uncomment the following line if using designed components
//InitializeComponent();
}
/// <summary>
/// Get User Control Html
/// use EnableSession=true if you are using session variables
/// </summary>
/// <returns>Html Table</returns>
[WebMethod(EnableSession = true)]
public string GetControlHtml(string controlLocation)
{
// Create instance of the page control
Page page = new Page();
// Create instance of the user control
UserControl userControl = (UserControl)page.LoadControl(controlLocation);
//Disabled ViewState- If required
//userControl.EnableViewState = false;
//Form control is mandatory on page control to process User Controls
HtmlForm form = new HtmlForm();
//Add user control to the form
form.Controls.Add(userControl);
//Add form to the page
page.Controls.Add(form);
//Write the control Html to text writer
StringWriter textWriter = new StringWriter();
//execute page on server
HttpContext.Current.Server.Execute(page, textWriter, false);
// Clean up code and return html
return CleanHtml(textWriter.ToString());
}
/// <summary>
/// Removes Form tags using Regular Expression
/// </summary>
private string CleanHtml(string html)
{
return Regex.Replace(html, @"<[/]?(form)[^>]*?>", "", RegexOptions.IgnoreCase);
}
}
请看 <input type="button" value="Load Customer Order" onclick="getData('~/Controls/GridView.ascx');" />
这个代码只是动态的加载了一下UserControl,但是我怎么样想这个UserControl传递一个参数呢?
把参数以querystring的方式写到URL里就可以了:
<input type="button" value="Load Customer Order" onclick="getData('~/Controls/GridView.ascx?id=xxx');"/>
如果这个参数需要在点击时从别的地方获取,而不是直接写到这里,可以修改getData():
function getData(controlLocation){
var url = controlLocation + "?id=" + xxx;
ScriptService.GetControlHtml(url, SucceededCallback, onFailedWS);
}
楼上正解。
感觉用创建一个Page来获取控件的输出代码的方式怪怪的,不如用一个Temlate来格式化输出或者直接构造String效率高.