最近有个项目用到,研究了下,基本成型,记于此。
需求:根据输入信息的不同,结合用户配置,加载不同的多个视图,形成Tab页,并异步加载数据。视图使用UserControl 可视化制作。
基本思路:
1. 先生成Tab页,在视图区域先加载一个Loading的图片。
2. 页尾生成Callback脚本。
3. App Code中,接收Callback方法调用,动态加载视图UserControl控件,Render到string中,返回到页面。
4. 页面接收"html"内容,并替换视图区域的Loading图片,加载完毕。
部分代码片段:
1. Tab Control 作用了JQuery UI 的Tab,并以Asp.net控件形式封装。
2. 将Callback部分,封装成CallbackPlaceHolder,可动态加裁任意用户控件。
3. 动态加裁UserControl.
4. 加载数据事,将UserControl Render到string.
5. 最后,结合之前在页面上生成的javascript脚本,将内容显示。
需求:根据输入信息的不同,结合用户配置,加载不同的多个视图,形成Tab页,并异步加载数据。视图使用UserControl 可视化制作。
基本思路:
1. 先生成Tab页,在视图区域先加载一个Loading的图片。
2. 页尾生成Callback脚本。
3. App Code中,接收Callback方法调用,动态加载视图UserControl控件,Render到string中,返回到页面。
4. 页面接收"html"内容,并替换视图区域的Loading图片,加载完毕。
部分代码片段:
1. Tab Control 作用了JQuery UI 的Tab,并以Asp.net控件形式封装。
Code
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
//base.Render(writer);
if (HasControls())
{
//<div id="tabs">
writer.AddAttribute(HtmlTextWriterAttribute.Id, "tabs");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
// <ul>
// <li><a href="#tabs-0">Tab 0</a></li>
// <li><a href="#tabs-1">Tab 1</a></li>
// <li><a href="#tabs-2">Tab 2</a></li>
//</ul>
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
for (int i = 0; i < Controls.Count; i++)
{
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.AddAttribute(HtmlTextWriterAttribute.Href, string.Format("#tabs-{0}", i));
writer.RenderBeginTag(HtmlTextWriterTag.A);
writer.RenderBeginTag(HtmlTextWriterTag.Span);
TabPage tabPage = Controls[i] as TabPage;
if (tabPage != null)
{
writer.Write(tabPage.Title);
}
else
{
//writer.Write(string.Format("Tab {0}", i));
}
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
writer.RenderEndTag();
// <div id="tabs-1">
// </div>
// <div id="tabs-2">
// </div>
// <div id="tabs-3">
// </div>
for (int i = 0; i < Controls.Count; i++)
{
writer.AddAttribute(HtmlTextWriterAttribute.Id, string.Format("tabs-{0}", i));
writer.RenderBeginTag(HtmlTextWriterTag.Div);
control.RenderControl(writer);
writer.RenderEndTag();
}
//</div>
writer.RenderEndTag();
}
else
{
//<div id="no-tabs">
writer.AddAttribute(HtmlTextWriterAttribute.Id, "no-tabs");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
//</div>
writer.RenderEndTag();
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
//<link type="text/css" href="css/smoothness/jquery-ui-1.7.2.custom.css" rel="stylesheet" />
var ui_css_link = new HtmlGenericControl("link");
ui_css_link.Attributes["type"] = "text/css";
ui_css_link.Attributes["href"] = "css/smoothness/jquery-ui-1.7.2.custom.css";
ui_css_link.Attributes["rel"] = "stylesheet";
Page.Header.Controls.Add(ui_css_link);
//<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
var jquery_script = new HtmlGenericControl("script");
jquery_script.Attributes["type"] = "text/javascript";
jquery_script.Attributes["src"] = "js/jquery-1.3.2.min.js";
Page.Header.Controls.Add(jquery_script);
//<script type="text/javascript" src="js/jquery-ui-1.7.2.custom.min.js"></script>
var ui_script = new HtmlGenericControl("script");
ui_script.Attributes["type"] = "text/javascript";
ui_script.Attributes["src"] = "js/jquery-ui-1.7.2.custom.min.js";
Page.Header.Controls.Add(ui_script);
//<script type="text/javascript">
// $(function()
// {
// $('#container-1 > ul').tabs();
// });
//</script>
var function_script = new HtmlGenericControl("script");
function_script.Attributes["type"] = "text/javascript";
function_script.InnerHtml = @"
$(function()
{
$('#tabs').tabs();
}
);
";
Page.Header.Controls.Add(function_script);
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
//base.Render(writer);
if (HasControls())
{
//<div id="tabs">
writer.AddAttribute(HtmlTextWriterAttribute.Id, "tabs");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
// <ul>
// <li><a href="#tabs-0">Tab 0</a></li>
// <li><a href="#tabs-1">Tab 1</a></li>
// <li><a href="#tabs-2">Tab 2</a></li>
//</ul>
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
for (int i = 0; i < Controls.Count; i++)
{
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.AddAttribute(HtmlTextWriterAttribute.Href, string.Format("#tabs-{0}", i));
writer.RenderBeginTag(HtmlTextWriterTag.A);
writer.RenderBeginTag(HtmlTextWriterTag.Span);
TabPage tabPage = Controls[i] as TabPage;
if (tabPage != null)
{
writer.Write(tabPage.Title);
}
else
{
//writer.Write(string.Format("Tab {0}", i));
}
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
writer.RenderEndTag();
// <div id="tabs-1">
// </div>
// <div id="tabs-2">
// </div>
// <div id="tabs-3">
// </div>
for (int i = 0; i < Controls.Count; i++)
{
writer.AddAttribute(HtmlTextWriterAttribute.Id, string.Format("tabs-{0}", i));
writer.RenderBeginTag(HtmlTextWriterTag.Div);
control.RenderControl(writer);
writer.RenderEndTag();
}
//</div>
writer.RenderEndTag();
}
else
{
//<div id="no-tabs">
writer.AddAttribute(HtmlTextWriterAttribute.Id, "no-tabs");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
//</div>
writer.RenderEndTag();
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
//<link type="text/css" href="css/smoothness/jquery-ui-1.7.2.custom.css" rel="stylesheet" />
var ui_css_link = new HtmlGenericControl("link");
ui_css_link.Attributes["type"] = "text/css";
ui_css_link.Attributes["href"] = "css/smoothness/jquery-ui-1.7.2.custom.css";
ui_css_link.Attributes["rel"] = "stylesheet";
Page.Header.Controls.Add(ui_css_link);
//<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
var jquery_script = new HtmlGenericControl("script");
jquery_script.Attributes["type"] = "text/javascript";
jquery_script.Attributes["src"] = "js/jquery-1.3.2.min.js";
Page.Header.Controls.Add(jquery_script);
//<script type="text/javascript" src="js/jquery-ui-1.7.2.custom.min.js"></script>
var ui_script = new HtmlGenericControl("script");
ui_script.Attributes["type"] = "text/javascript";
ui_script.Attributes["src"] = "js/jquery-ui-1.7.2.custom.min.js";
Page.Header.Controls.Add(ui_script);
//<script type="text/javascript">
// $(function()
// {
// $('#container-1 > ul').tabs();
// });
//</script>
var function_script = new HtmlGenericControl("script");
function_script.Attributes["type"] = "text/javascript";
function_script.InnerHtml = @"
$(function()
{
$('#tabs').tabs();
}
);
";
Page.Header.Controls.Add(function_script);
}
2. 将Callback部分,封装成CallbackPlaceHolder,可动态加裁任意用户控件。
Code
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
//<script type="text/javascript">
// function ClientCallback_PlaceHolder_xxxx(result, context)
// {
// $("#callback_placeholder_xxxx").html(result);
// }
//</script>
var function_script = new HtmlGenericControl("script");
function_script.Attributes["type"] = "text/javascript";
function_script.InnerHtml = string.Format(@"
function ClientCallback_PlaceHolder_{0}(result, context)
{{
$('#callback_placeholder_{0}').html(result);
}}
", this.CallbackID);
Page.Header.Controls.Add(function_script);
// <script type="text/javascript">function GetViewData_Callback_xxxx(arg, context) { WebForm_DoCallback('__Page',arg,ClientCallback_PlaceHolder_xxxx,context,null,true); }</script>
string callbackEventReference = Page.ClientScript.GetCallbackEventReference(Page, "arg", string.Format("ClientCallback_PlaceHolder_{0}", this.CallbackID), "context", true);
string clientFunction = string.Format("function GetViewData_Callback_{0}(arg, context) {{ {1}; }}", this.CallbackID, callbackEventReference);
var clientFunction_script = new HtmlGenericControl("script");
clientFunction_script.Attributes["type"] = "text/javascript";
clientFunction_script.InnerHtml = clientFunction;
Page.Header.Controls.Add(clientFunction_script);
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
//base.Render(writer);
//<div id="callback_placeholder_xxx">
writer.AddAttribute(HtmlTextWriterAttribute.Id, string.Format("callback_placeholder_{0}", this.CallbackID));
writer.RenderBeginTag(HtmlTextWriterTag.Div);
//<img src="images/loading.gif"></img>
writer.AddAttribute(HtmlTextWriterAttribute.Src, "images/loading.gif");
writer.RenderBeginTag(HtmlTextWriterTag.Img);
writer.RenderEndTag();
writer.RenderEndTag();
Page.ClientScript.RegisterStartupScript(GetType(), string.Format("STARTUP_SCRIPT_KEY_CALLBACK_{0}", this.CallbackID), string.Format("GetViewData_Callback_{0}('{0}', '{0}');", this.CallbackID), true);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
//<script type="text/javascript">
// function ClientCallback_PlaceHolder_xxxx(result, context)
// {
// $("#callback_placeholder_xxxx").html(result);
// }
//</script>
var function_script = new HtmlGenericControl("script");
function_script.Attributes["type"] = "text/javascript";
function_script.InnerHtml = string.Format(@"
function ClientCallback_PlaceHolder_{0}(result, context)
{{
$('#callback_placeholder_{0}').html(result);
}}
", this.CallbackID);
Page.Header.Controls.Add(function_script);
// <script type="text/javascript">function GetViewData_Callback_xxxx(arg, context) { WebForm_DoCallback('__Page',arg,ClientCallback_PlaceHolder_xxxx,context,null,true); }</script>
string callbackEventReference = Page.ClientScript.GetCallbackEventReference(Page, "arg", string.Format("ClientCallback_PlaceHolder_{0}", this.CallbackID), "context", true);
string clientFunction = string.Format("function GetViewData_Callback_{0}(arg, context) {{ {1}; }}", this.CallbackID, callbackEventReference);
var clientFunction_script = new HtmlGenericControl("script");
clientFunction_script.Attributes["type"] = "text/javascript";
clientFunction_script.InnerHtml = clientFunction;
Page.Header.Controls.Add(clientFunction_script);
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
//base.Render(writer);
//<div id="callback_placeholder_xxx">
writer.AddAttribute(HtmlTextWriterAttribute.Id, string.Format("callback_placeholder_{0}", this.CallbackID));
writer.RenderBeginTag(HtmlTextWriterTag.Div);
//<img src="images/loading.gif"></img>
writer.AddAttribute(HtmlTextWriterAttribute.Src, "images/loading.gif");
writer.RenderBeginTag(HtmlTextWriterTag.Img);
writer.RenderEndTag();
writer.RenderEndTag();
Page.ClientScript.RegisterStartupScript(GetType(), string.Format("STARTUP_SCRIPT_KEY_CALLBACK_{0}", this.CallbackID), string.Format("GetViewData_Callback_{0}('{0}', '{0}');", this.CallbackID), true);
}
3. 动态加裁UserControl.
// view = "~/Views/DataGridView.ascx"
IView control = (IView)LoadControl(view);
control.ViewInfo = viewInfo;
this.TabWorkspaceMain.Show(control, viewInfo.SmartPartInfo);
IView control = (IView)LoadControl(view);
control.ViewInfo = viewInfo;
this.TabWorkspaceMain.Show(control, viewInfo.SmartPartInfo);
4. 加载数据事,将UserControl Render到string.
Code
public string GetViewContent(object smartPart)
{
// TODO:
StringWriter stringWriter = new StringWriter();
HtmlTextWriter writter = new HtmlTextWriter(stringWriter);
Control control = smartPart as Control;
if (control != null)
{
control.RenderControl(writter);
}
return stringWriter.ToString();
}
public string GetViewContent(object smartPart)
{
// TODO:
StringWriter stringWriter = new StringWriter();
HtmlTextWriter writter = new HtmlTextWriter(stringWriter);
Control control = smartPart as Control;
if (control != null)
{
control.RenderControl(writter);
}
return stringWriter.ToString();
}
5. 最后,结合之前在页面上生成的javascript脚本,将内容显示。
function ClientCallback_PlaceHolder_xxx(result, context)
{
$('#callback_placeholder_xxx').html(result);
}
{
$('#callback_placeholder_xxx').html(result);
}