asp.net 后台多线程异步处理时的 进度条实现一(Ajax+Ashx实现以及封装成控件的实现)

  工作好长时间了,这期间许多功能也写成了不少的控件来使用,但是,都只是为了代码的结构清析一些而已。而这一次,我决定完成一个我一直在网上寻找却没寻找到的功能。就是,在异步(比如说,后台的数据库备份、后台的文件加解密这类操作)时,前台假死的情况。asp自带了updatePanel,里面可以放一个自带的progress控件,怎么说呢,这就是一个显示而已,而且根本不能动。当你在备份数据的时候,你点备份,然后上面显示“请等待....”,这叫progress,我擦。不过,微软官方给了解释了,说许多人习惯了观察浏览器状态栏上面的进度条,我想说那个条子好假,不信你试试。

  好了,下面来说一下我做的这个东西,当然,我先用ajax+ashx的方式想办法让它实现,下面是我设计前期自己画的一张图:

这张图上面有错误,但是,作为我的第一个想法,我觉得它功不可没,后面的图都是在它的基础上修改而来了,它也代表了我的初始想法,以及相关的知识残缺。

  图中已经可以把我大部分的想法表达出来了,当然会有人说,通常ajax轮询进度都是这么实现的。但是,却没有人将它封装成服务器控件。

  先说图中明显的错误:

    1、异步操作的时候,一旦请求终断,线程则无法再访问到session,这是一个致命的异常。因为,我本来打算以session来保存信息,并依靠session的机制来释放我已经保存的内容,可以省下好多流程与精力,但事实证明,我还是太年轻了~~。所以,我改用了application,写就了我的第一个后台ashx文件:

  

  1. 1 public class AjaxAction : IHttpHandler, IReadOnlySessionState
  2. 2 {
  3. 3
  4. 4 public void ProcessRequest(HttpContext context)
  5. 5 {
  6. 6 context.Response.ContentType = "text/plain";
  7. 7 if (context.Request.QueryString["Action"] != null)
  8. 8 {
  9. 9 string command = context.Request.QueryString["Action"].ToString();
  10. 10 System.Reflection.MethodInfo method = this.GetType().GetMethod(command);
  11. 11 if (method != null)
  12. 12 {
  13. 13 method.Invoke(this, new object[] { context });
  14. 14 }
  15. 15 }
  16. 16 }
  17. 17
  18. 18 public void ProgressMothed(HttpContext context)
  19. 19 {
  20. 20 string guid = HttpContext.Current.Session.SessionID.ToString().Trim() + DateTime.Now.ToString("HHmmssffffff").Trim();
  21. 21 Thread th = new Thread(
  22. 22 delegate()
  23. 23 {
  24. 24 for (int i = 0; i < 101; i++)
  25. 25 {
  26. 26 Thread.Sleep(100);
  27. 27 context.Application[guid] = i;
  28. 28 context.Response.Write(i.ToString());
  29. 29 }
  30. 30
  31. 31 }
  32. 32 );
  33. 33 th.IsBackground = true;
  34. 34 try
  35. 35 {
  36. 36 th.Start();
  37. 37 context.Application.Add(guid, 0);
  38. 38 context.Response.Write(guid);
  39. 39 }
  40. 40 catch (Exception ex)
  41. 41 {
  42. 42 context.Response.Write("-1");
  43. 43 }
  44. 44 }
  45. 45 public void GetPercentMethod(HttpContext context)
  46. 46 {
  47. 47 try
  48. 48 {
  49. 49 string guid = context.Request.QueryString["guid"].ToString();
  50. 50 string per = context.Application[guid].ToString();
  51. 51 context.Response.Write(per);
  52. 52 }
  53. 53 catch (Exception ex)
  54. 54 {
  55. 55 context.Response.Write("-1");
  56. 56 }
  57. 57 }
  58. 58 public bool IsReusable
  59. 59 {
  60. 60 get
  61. 61 {
  62. 62 return false;
  63. 63 }
  64. 64 }
  1. 1 <script type="text/javascript"> 8 function AjaxMethod() {
  2. 9 $.ajax({
  3. 10 url:location.href,
  4. 12 data: { Action: "ProgressMethod", ts: (new Date).getTime() },
  5. 13 success: function (data) {
  6. 14 if (!(data == undefined || data == null || data == "")) {
  7. 15 if (data != "-1") {
  8. 16 AjaxGetPercent(data);
  9. 17 } else {
  10. 18 alert("此处理过程暂时无法连接,请稍后再试");
  11. 19 }
  12. 20 } else {
  13. 21 alert("访问的处理不存在,请刷新后重试["+data+"]");
  14. 22 }
  15. 23 }
  16. 24 });
  17. 25 }
  18. 26 function AjaxGetPercent(guid) {
  19. 27 $.ajax({
  20. 28 url: location.href,
  21. 30 data: { Action: "GetPercentMethod",guid:guid, ts: (new Date).getTime() },
  22. 31 success: function (data) {
  23. 32 if (data != "-1") {
  24. 33 if (data < 100) {
  25. 34 $("#progress_ensleep_pb").css("display", "block");
  26. 35 $("#progress_ensleep_text").html(data);
  27. 36 $("#progress_ensleep_pgress").css("width", data + "%");
  28. 37 setTimeout(AjaxGetPercent(guid), 50);
  29. 38 } else {
  30. 39 $("#progress_ensleep_pgress").css("width", "100%");43 $("#progress_ensleep_text").html(100);
  31. 45 }
  32. 46 } else {
  33. 47 alert("操作过程中出现异常,请重试");
  34. 48 }
  35. 49 }
  36. 50 });
  37. 51 }
  38. 52 </script>

  可以看出,我完全按照我当初的想法来做的,只是加了一些容错机制,试验了一下,一个进度条在一个页面上,完成正常,并且加入了样式,非常好看。但是,如果一个页面上有十个怎么办?这种情况很多,很常见。而且,每一个方法都要写在ashx这个文件中,人家aspx.cs里面的东西凭什么往你ashx里面写?这样的结果当然就是,我的整个项目乱成面条(打了两局dota的时间煮的面条)——看看不清,理理不起来。想做成引入型的,只能做成控件。

  但是,做成控件有以下几个问题:

    1、一个页面上要放n个控件,前台要为每个控件完成情况执行相应的js回调函数。

    2、这个控件正在执行的时候,如果页面回传,完了之后,它必须继续跑,并且像没回传一样。

    3、事件!!!!

  先说第三个,事件:

  因为控件的目的是执行异步操作,可以看见,我使用了子线程来处理,而子线程是由委托控件。一开始我是想,这是控件,我为什么放着事件不用呢?我把这个子线程要用到的方法写成一个事件,由aspx.cs给这个事件写方法体,不就可以了么?事实证明,我又秀了一次我的年轻~~~,ajax回传的时候,根本就不会触发控件的这一类事件,之所以说这一类,是因为像on_load()这些还是触发的,但是,它是要处理管道管理的,而按钮的onclick之类的无法触发,因为ajax没有带viewstate过来。这就导致了,我的每一次ajax都不是postback,我了个擦啊~~0~~。然后我开始收集信息,就像三国杀逆风时你要数数剩余的牌,dota逆风时你要看一看地图上每一个红点闪现时它的装备,war3时拼死一个步兵或者大g小g冲进对面看一看对面建筑一样……,然后我发现,我可以用的只有ajax带一的context以及session这两个东西,当然后台还有一个application,我不把它放入我的考虑范围(你被虐惨了,你会想着你家还有一个牛逼的泉水么?)。然后我使用了委托,是的,写了一个委托成员。然后爆露出一个成员方法以释放被使用的application(编码习惯良好,反正比南京的空气要好得多~~~)。

  再说第第一个和第二个,

    js回调方法:我把这个抛给使用者写了,放在aspx页面,只要把函数设到控件的属性里面就可以了,然后在控件生成的时候,将这个方法名写到回调的地方。然后为控件生成的所有的js方法都起唯一的名字,即 将控件的ClientID放在方法的后面。这使得一个页面上可以实现多个控件。

    回调后状态的还原继续:我在控件的On_load方法里面,每一次都查找看是否有可用的application,如果有,即会生成一个$(documeent).ready(function(){...}),里面会直接调用对percent(即当前进度)的ajax请求。

  下面上代码:

  1. 1 <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AjaxProgress.ascx.cs" Inherits="ESLib.Controls.AjaxProgress" %>
  2. 2 <script type="text/javascript">if (!window.jQuery) alert("使用AjaxProgress必须引用jquery!");</script>
  3. 3 <script type="text/javascript">
  4. 4 $(document).ready(function () {
  5. 5 <% if (this.guid != null && this.guid != "")
  6. 6 {%>
  7. 7 <%="AjaxGetPercent_"+this.ClientID+"('"+this.guid+"');"%>
  8. 8 <%}%>
  9. 9 });
  10. 10 function AjaxMethod_<%=this.ClientID%>(clientid) {
  11. 11 $.ajax({
  12. 12 url:location.href,
  13. 13 //content: "Action=ProgressMethod&ClientID=" + clientid + "&ts=" + (new Date).getTime(),
  14. 14 data: { Action: "ProgressMethod", ClientID: '<%=this.ClientID%>', ts: (new Date).getTime() },
  15. 15 success: function (data) {
  16. 16 if (!(data == undefined || data == null || data == "")) {
  17. 17 if (data != "-1") {
  18. 18 AjaxGetPercent_<%=this.ClientID%>(data);
  19. 19 } else {
  20. 20 alert("此处理过程暂时无法连接,请稍后再试");
  21. 21 }
  22. 22 } else {
  23. 23 alert("访问的处理不存在,请刷新后重试["+data+"]");
  24. 24 }
  25. 25 }
  26. 26 });
  27. 27 }
  28. 28 function AjaxGetPercent_<%=this.ClientID%>(guid) {
  29. 29 $.ajax({
  30. 30 url: location.href,
  31. 31 //content: "Action=GetPercentMethod&ClientID=" + clientid + "&guid=" + guid + "&ts=" + (new Date).getTime(),
  32. 32 data: { Action: "GetPercentMethod", ClientID: '<%=this.ClientID%>',guid:guid, ts: (new Date).getTime() },
  33. 33 success: function (data) {
  34. 34 if (data != "-1") {
  35. 35 if (data < 100) {
  36. 36 $("#progress_ensleep_pb_<%=this.ClientID%>").css("display", "block");
  37. 37 $("#progress_ensleep_text_<%=this.ClientID%>").html(data);
  38. 38 $("#progress_ensleep_pgress_<%=this.ClientID%>").css("width", data + "%");
  39. 39 setTimeout(AjaxGetPercent_<%=this.ClientID%>(guid), 50);
  40. 40 } else {
  41. 41 $("#progress_ensleep_pgress_<%=this.ClientID%>").css("width", "100%");
  42. 42 if ("<%=this.CloseWhenEnd.Trim()%>" == "true") {
  43. 43 $("#progress_ensleep_pb_<%=this.ClientID%>").css("display", "none");
  44. 44 }
  45. 45 $("#progress_ensleep_text_<%=this.ClientID%>").html(100);
  46. 46 <%=this.JsSuccessCallBack%>
  47. 47 }
  48. 48 } else {
  49. 49 alert("操作过程中出现异常,请重试");
  50. 50 }
  51. 51 }
  52. 52 });
  53. 53 }
  54. 54 </script>
  55. 55 <style type="text/css">
  56. 56 .progressContentensleep{
  57. 57 background-color:blue;
  58. 58 height:30px;
  59. 59 float:left;
  60. 60 width:300px;
  61. 61 }
  62. 62 .progressInnerensleep {
  63. 63 background-color:green;
  64. 64 height:30px;
  65. 65 }
  66. 66 .progressSpanensleep{
  67. 67 color:white;
  68. 68 height:30px;
  69. 69 line-height:30px;
  70. 70 margin-top:-30px;
  71. 71 }
  72. 72 </style>
  73. 73 <div>
  74. 74 <div style="display:none">
  75. 75 </div>
  76. 76 <div id='progress_ensleep_pb_<%=this.ClientID.Trim() %>' class='<%=this.OuterCssClass %>' style='display: none'>
  77. 77 <div id='progress_ensleep_pgress_<%=this.ClientID.Trim() %>' class='<%=this.InnerCssClass %>' style="width:0%">
  78. 78 </div>
  79. 79 <div id='progress_ensleep_span_<%=this.ClientID.Trim() %>' class='<%=this.TextCss %>'><%=this.WarmText.Substring(0,this.WarmText.IndexOf('{')) %><span id='progress_ensleep_text_<%=this.ClientID.Trim() %>'"></span><%=this.WarmText.Substring(this.WarmText.IndexOf('}')+1,this.WarmText.Length-this.WarmText.IndexOf('}')-1) %></div>
  80. 80 </div>
  81. 81 </div>

控件的cs代码:

  1. 1 using System;
  2. 2 using System.Collections.Generic;
  3. 3 using System.ComponentModel;
  4. 4 using System.Linq;
  5. 5 using System.Threading;
  6. 6 using System.Web;
  7. 7 using System.Web.UI;
  8. 8 using System.Web.UI.WebControls;
  9. 9
  10. 10 namespace ESLib.Controls
  11. 11 {
  12. 12 [ToolboxData("<{0}:AjaxProgress runat=server></{0}:AjaxProgress>")]
  13. 13 [ToolboxItem(true)]
  14. 14 public partial class AjaxProgress : System.Web.UI.UserControl
  15. 15 {
  16. 16 [Description("完成提示,如‘完成{0}%’")]
  17. 17 public string WarmText
  18. 18 {
  19. 19 get { return ViewState[this.ClientID.Trim()+"hfWarmText"].ToString() == "" ? "目前已完成{0}%" : ViewState[this.ClientID.Trim()+"hfWarmText"].ToString(); }
  20. 20 set {
  21. 21 ViewState[this.ClientID.Trim()+"hfWarmText"] = value;
  22. 22 }
  23. 23
  24. 24 }
  25. 25 [Description("进度条内芯样式类")]
  26. 26 public string InnerCssClass
  27. 27 {
  28. 28 get { return ViewState[this.ClientID.Trim()+"hfinnerCss"].ToString() == "" ? "progressInnerensleep" : ViewState[this.ClientID.Trim()+"hfinnerCss"].ToString(); }
  29. 29 set {
  30. 30 ViewState[this.ClientID.Trim()+"hfinnerCss"] = value;
  31. 31 }
  32. 32 }
  33. 33
  34. 34 public string CloseWhenEnd
  35. 35 {
  36. 36 get { return ViewState[this.ClientID.Trim()+"hfCloseWhenEnd"].ToString() == "" ? "true" : ViewState[this.ClientID.Trim()+"hfCloseWhenEnd"].ToString() == "true" ? "true" : "false"; }
  37. 37 set {
  38. 38 ViewState[this.ClientID.Trim()+"hfCloseWhenEnd"]= value;
  39. 39 }
  40. 40 }
  41. 41 [Description("进度条容器样式类")]
  42. 42 public string OuterCssClass
  43. 43 {
  44. 44 get { return ViewState[this.ClientID.Trim()+"hfouterCss"].ToString() == "" ? "progressContentensleep" : ViewState[this.ClientID.Trim()+"hfouterCss"].ToString(); }
  45. 45 set
  46. 46 {
  47. 47 ViewState[this.ClientID.Trim()+"hfouterCss"] = value;
  48. 48 }
  49. 49 }
  50. 50
  51. 51 [Description("进度条文字样式类")]
  52. 52 public string TextCss
  53. 53 {
  54. 54 get { return ViewState[this.ClientID.Trim()+"hftextCss"].ToString() == "" ? "progressSpanensleep" : ViewState[this.ClientID.Trim()+"hftextCss"].ToString(); }
  55. 55 set
  56. 56 {
  57. 57 ViewState[this.ClientID.Trim()+"hftextCss"] = value;
  58. 58 }
  59. 59 }
  60. 60 [Description("达到100%后要执行的js方法,如:js()")]
  61. 61 public string JsSuccessCallBack
  62. 62 {
  63. 63 get { return ViewState[this.ClientID.Trim() + "hfJsSuccessCallBack"].ToString(); }
  64. 64 set {
  65. 65 ViewState[this.ClientID.Trim()+"hfJsSuccessCallBack"] = value;
  66. 66 }
  67. 67 }
  68. 68 [Description("进度条唯一标志符")]
  69. 69 public string guid
  70. 70 {
  71. 71 get {
  72. 72 try
  73. 73 {
  74. 74 return HttpContext.Current.Request.Cookies[this.ClientID.Trim() + "guid"] == null ? "" : HttpContext.Current.Request.Cookies[this.ClientID.Trim() + "guid"].Value.ToString();
  75. 75 }
  76. 76 catch (Exception ex)
  77. 77 {
  78. 78 return "";
  79. 79 }
  80. 80 }
  81. 81 set
  82. 82 {
  83. 83 HttpCookie c = new HttpCookie(this.ClientID.Trim() + "guid");
  84. 84 c.Value = value;
  85. 85 HttpContext.Current.Response.Cookies.Add(c);
  86. 86 }
  87. 87 }
  88. 88
  89. 89 public delegate void DoMethodDelegate(object guid);
  90. 90 public DoMethodDelegate DoMethod;
  91. 91
  92. 92 public void End(object guid)
  93. 93 {
  94. 94 Application.Remove(guid as String);
  95. 95 }
  96. 96 protected void Page_Load(object sender, EventArgs e)
  97. 97 {
  98. 98 if (!IsPostBack)
  99. 99 {
  100. 100 ViewState[this.ClientID.Trim()+"hfWarmText"] = ViewState[this.ClientID.Trim()+"hfWarmText"] == null ? "" : ViewState[this.ClientID.Trim()+"hfWarmText"];
  101. 101 ViewState[this.ClientID.Trim()+"hfinnerCss"] = ViewState[this.ClientID.Trim()+"hfinnerCss"] == null ? "" : ViewState[this.ClientID.Trim()+"hfinnerCss"];
  102. 102 ViewState[this.ClientID.Trim()+"hfouterCss"] = ViewState[this.ClientID.Trim()+"hfouterCss"] == null ? "" : ViewState[this.ClientID.Trim()+"hfouterCss"];
  103. 103 ViewState[this.ClientID.Trim()+"hftextCss"] = ViewState[this.ClientID.Trim()+"hftextCss"] == null ? "" : ViewState[this.ClientID.Trim()+"hftextCss"];
  104. 104 ViewState[this.ClientID.Trim()+"hfJsSuccessCallBack"] = ViewState[this.ClientID.Trim()+"hfJsSuccessCallBack"] == null ? "" : ViewState[this.ClientID.Trim()+"hfJsSuccessCallBack"];
  105. 105 ViewState[this.ClientID.Trim() + "hfCloseWhenEnd"] = ViewState[this.ClientID.Trim() + "hfCloseWhenEnd"] == null ? "" : ViewState[this.ClientID.Trim() + "hfCloseWhenEnd"];
  106. 106 }
  107. 107 else
  108. 108 {
  109. 109 }
  110. 110 if (HttpContext.Current.Request.QueryString["Action"] != null)
  111. 111 {
  112. 112 HttpContext.Current.Response.Clear();
  113. 113 if (HttpContext.Current.Request.QueryString["ClientID"] != null && (HttpContext.Current.Request.QueryString["ClientID"].ToString().Trim() == this.ClientID.Trim()))
  114. 114 {
  115. 115 HttpContext.Current.Response.ContentType = "text/plain";
  116. 116 if (HttpContext.Current.Request.QueryString["Action"] != null)
  117. 117 {
  118. 118 string command = HttpContext.Current.Request.QueryString["Action"].ToString();
  119. 119 System.Reflection.MethodInfo method = this.GetType().GetMethod(command);
  120. 120 if (method != null)
  121. 121 {
  122. 122 method.Invoke(this,null);
  123. 123 }
  124. 124 }
  125. 125 }
  126. 126 }
  127. 127 }
  128. 128
  129. 129 public void ProgressMethod()
  130. 130 {
  131. 131 string guid = HttpContext.Current.Session.SessionID.ToString().Trim() + DateTime.Now.ToString("HHmmssffffff").Trim();
  132. 132 //Thread th = new Thread(DoMethod(guid));
  133. 133 try
  134. 134 {
  135. 135 ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoMethod), guid);//未找到处理程序
  136. 136 Application.Add(guid, 0);
  137. 137 this.guid= guid;
  138. 138 HttpContext.Current.Response.Write(guid);
  139. 139 }
  140. 140 catch (Exception ex)
  141. 141 {
  142. 142 HttpContext.Current.Response.Write("-1");
  143. 143
  144. 144 }
  145. 145 HttpContext.Current.Response.End();
  146. 146 }
  147. 147 public void GetPercentMethod()
  148. 148 {
  149. 149 try
  150. 150 {
  151. 151 string guid = HttpContext.Current.Request.QueryString["guid"].ToString();
  152. 152 if (Application[guid] != null)
  153. 153 {
  154. 154 HttpContext.Current.Response.Write(Application[guid].ToString());
  155. 155 }
  156. 156 else
  157. 157 {
  158. 158 HttpCookie c = new HttpCookie(this.ClientID.Trim() + "guid");
  159. 159 c.Expires = DateTime.Now.AddDays(-1);
  160. 160 HttpContext.Current.Response.Cookies.Add(c);
  161. 161 HttpContext.Current.Response.Write("100");
  162. 162 }
  163. 163 }
  164. 164 catch (Exception ex)
  165. 165 {
  166. 166 HttpContext.Current.Response.Write("-1");
  167. 167 }
  168. 168 HttpContext.Current.Response.End();
  169. 169 }
  170. 170 }
  171. 171 }

由于时间问题,就不多说了,代码全在这里了,我是觉得,我被这个东西挡了好多次了,然后网上一直没有类似的控件,让人着实难受。

写好的文件在这里,http://url.cn/OK26ls (密码:SEvf)

下面是用法,测试的童鞋可以看一下:

使用说明:

<UC:AjaxProgress runat = "server" ID = "AjaxProgress2" JsSuccessCallBack = "sucessajax3()" InnerCssClass = "progressInner" OuterCssClass = "progressContent" WarmText = "{0}%" TextCss = "progressSpan" CloseWhenEnd="false" />

说明:

属性

  1. JsSuccessCallBack       进度达到100%后执行的js函数
  2. InnerCssClass           进度条内条样式类
  3. OuterCssClass           进度条窗口样式类
  4. WarmText                提示文字,{0}为百分数(无百分号)的通配符
  5. TextCss             显示进度文件样式类
  6. CloseWhenEnd            进度完成后是否关闭进度条,false不关闭,其它情况默认为关闭

事件:

AjaxProgress2.DoMethod = DoMethod2;
public void DoMethod2(object guid)

{

for (int i = 0; i < 101; i++)

{

Thread.Sleep(500);

Application[guid as String] = i;

}

}

在aspx.cs中,必须要声明一个方法,并且将此方法赋值给控件的委托DoMethod

触发进度条函数为:

AjaxMethod _【AjaxProgress的ClientID】()

解析:

AjaxProgress的ClientID,即在浏览器中的id,由于没有呈现器,所以,此处与ID相同,即样例中的AjaxProgress2。

例如:

<asp:Button runat = "server" ID="Button2" Text = "执行3" OnClientClick = "AjaxMethod_AjaxProgress2();return false;" />

进度条后台执行事件:

数据委托定义:public delegate void DoMethodDelegate(object guid);

所以,可以定义成如下:

public void DoMethod2(object guid)
{
for (int i = 0; i < 101; i++)
{
Thread.Sleep(500);
Application[guid as String] = i;
}
AjaxProgress2.End(guid);
}

 
 

Ajax+Ashx实现以及封装成控件的实现的更多相关文章

  1. asp.net 后台多线程异步处理时的 进度条实现一(Ajax+Ashx实现以及封装成控件的实现)

    (更新:有的同学说源代码不想看,说明也不想看,只想要一个demo,这边提供一下:http://url.cn/LPT50k (密码:TPHU)) 工作好长时间了,这期间许多功能也写成了不少的控件来使用, ...

  2. 一种开发模式:ajax + ashx + UserControl

    一.ajax+ashx模式的缺点     在web开发过程中,为了提高网站的用户体验,或多或少都会用到ajax技术,甚至有的网站全部采用ajax来实现,大量使用ajax在增强用户体验的同时会带来一些负 ...

  3. 9.2.3 .net core 通过TagHelper封装控件

    .net core 除了继续保留.net framework的HtmlHelper的写法以外,还提供了TagHelper和ViewComponent方式生成控件. 我们本节说的是使用TagHelper ...

  4. Atitit.auto complete 自动完成控件的实现总结

    Atitit.auto complete  自动完成控件的实现总结 1. 框架选型 1 2. 自动完成控件的ioc设置 1 3. Liger  自动完成控件问题 1 4. 官网上的code有问题,不能 ...

  5. [转]9.2.3 .net core 通过TagHelper封装控件

    本文转自:https://www.cnblogs.com/BenDan2002/p/6170624.html .net core 除了继续保留.net framework的HtmlHelper的写法以 ...

  6. 9.2.4 .net core 通过ViewComponent封装控件

    我们在.net core中还使用了ViewComponent方式生成控件.ViewComponent也是asp.net core的新特性,是对页面部分的渲染,以前PartialView的功能,可以使用 ...

  7. [转].net core 通过ViewComponent封装控件 左侧菜单

    本文转自:http://www.cnblogs.com/BenDan2002/p/6224816.html 我们在.net core中还使用了ViewComponent方式生成控件.ViewCompo ...

  8. 对jquery的ajax进行二次封装

    第一种方法: $(function(){ /** * ajax封装 * url 发送请求的地址 * data 发送到服务器的数据,数组存储,如:{"username": " ...

  9. Silverlight动态生成控件实例

    刚学习Silverlight,做了一个动态创建控件的实例 实现结果:根据已有的控件类名称,得到控件的实例化对象 实现思路1:就是定义一个模板文件,将类名做为参数,在silverlight中使用Srea ...

随机推荐

  1. 记得12306货运系统“抢购空”编写插件--chrome交互式插件的各个部分

    --chrome交互式插件的各个部分 Chrome插件的基础知识就不多说了.随便找个新手教程就能够上手了,比如官方提供的Overview与Getting Started教程足够入门了:笔者也是现学现卖 ...

  2. Skynumber

    Time Limit: 1000ms Memory Limit: 128000KB 64-bit integer IO format:      Java class name: Submit Sta ...

  3. SharePoint 2013 如何使用Silverlight

    1.打开VS,创建一个Silverlight计划.例如下面的附图: 2.配置选择默认的,当然也能够不勾选Host Application,例如以下图: 3.加入Silverlight控件,2个labe ...

  4. 虚拟化(一):虚拟化和vmware产品描述

    由于公司最近取得了虚拟化监控,因此,我们需要虚拟化的认识,总结学习,对于虚拟化的概念.从百度百科,例如下列:         虚拟化.是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机.在一台计算机上 ...

  5. hdu 最大三角形(凸包+旋转卡壳)

    老师在计算几何这门课上给Eddy布置了一道题目,题目是这样的:给定二维的平面上n个不同的点,要求在这些点里寻找三个点,使他们构成的三角形拥有的面积最大.Eddy对这道题目百思不得其解,想不通用什么方法 ...

  6. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    ...

  7. MyEclipse下一个XFire发展Webservice示例

    最近的研究JAVA发展Webservice.网络发现几个热门选择AXIS.XFire.CFX(XFire下一代),打开前几天对这篇文章比较三种选择,他们已经有了一些概念. 样本,以确定自己的实践 在開 ...

  8. hdu1881 毕业bg(深搜索dfs)

    主题链接:pid=1881">http://acm.hdu.edu.cn/showproblem.php? pid=1881 ----------------------------- ...

  9. crawler_爬虫分布式设计图收集_01

  10. 小强HTML5手机发展之路(52)——jquerymobile触摸互动

    当使用移动设备的触摸操作,最常用的是点击.按住屏幕或手势,jQuery Mobile能够通过触摸事件绑定行为来响应用户的特定触摸. 一个.点击并按住 直接在代码(在代码中的一切,它使产品!) < ...