(九)ASP.NET自定义用户控件(2)
http://www.cnblogs.com/SkySoot/archive/2012/09/04/2670678.html
用户控件
在 .NET 里,可以通过两种方式把自己的控件插入到 Web 窗体框架中:
- 用户控件:它是一小段页面,可以包括静态 HTML 代码和 Web 服务器控件。用户控件的好处是一旦创建了它,就可以在同一个 Web 应用程序的多个页面重用它。用户控件可以加入自己的属性,事件和方法。
- 自定义服务器控件:它是被编译的类,它通过编程生成自己的 HTML 。服务器控件总是预编译到 DLL 程序集。根据你编写服务器控件的方式,可以从零开始呈现它的内容,继承一个现有的服务器控件的外观和行为并扩展它的功能,或者通过实例化和配置一组组合控件来创建界面。
用户控件基础
用户控件由一个含有控件标签的界面部分(.ascx 文件)以及嵌入脚本或一个在后台的 cs 文件组成。用户控件几乎可以包括所有的内容(HTML,ASP.NET 控件),还可接收 Page 对象的事件(如 Load 和 PreRender),并通过属性公开一组相同的 ASP.NET 固有的对象(如 Application、Session、Request、Response)。
用户控件和网页之间的主要区别如下:
- 用户控件以 Control 指令而不是 Page 指令开头。
- 用户控件使用的扩展名是 .ascx 而不是 .aspx 。
- 用户控件后台代码从 System.Web.UI.UserControl 类继承。(其实 UserControl 类和 Page 类 继承自同一个 TemplateControl 类,这就是他们共享这么多共同方法和事件的原因)
- 用户控件不能被客户端浏览器直接请求,用户控件需要嵌入到其他网页里。
创建简单的用户控件
用户控件是一个分部类。它会和 ASP.NET 自动生成的独立部分合并。要测试用户控件,必须把它放入一个 Web 窗体上。通过 Register 指令告诉 ASP.NET 你要使用一个用户控件:
- <%@ Register Src="Header.ascx" TagName="Header" TagPrefix="apress" %>
src 指定了用户控件的源文件;TagPrefix 特性指定了页面上声明新控件的标签前缀;TagName 特性指定了页面上用户控件的标签名。
下面是示例完整的用户控件代码和页面代码:
- <%@ Control Language="C#" AutoEventWireup="true" CodeFile="Header.ascx.cs" Inherits="Chapter15_Header" %>
- <table width="100%" border="0" style="">>
- <tr>
- <td align="center">
- <b style="color:White; font-size:60px">User Control Test Page</b>
- </td>
- </tr>
- <tr>
- <td align="right">
- <b style="color:White">An Apress Creation 2008</b>
- </td>
- </tr>
- </table>
- <%@ Page Language="C#" AutoEventWireup="true" CodeFile="HeaderTest.aspx.cs" Inherits="Chapter15_HeaderTest" %>
- <%@ Register Src="Header.ascx" TagName="Header" TagPrefix="apress" %>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title>HeaderHost</title>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <apress:Header ID="Header1" runat="server" />
- </div>
- </form>
- </body>
- </html>
把页面转换为用户控件
其实,开发用户控件最快捷的方式是把它先放到一个网页里,测试后再把它转换为一个用户控件。即使不采用这种开发方式,你仍然可能需要把页面的用户界面的某部分提取出来并在多个地方重用。
大体上,这就是一个剪切 - 粘贴 的操作,不过应该注意以下几点:
- 删除所有 <html>、<head>、<body>、<form> 标签。(在一个页面里这些标签只能出现一次)
- 将页面的 Page 指令更改为 Control 指令,并去除 Control 指令不支持的那些特性。
- 如果没有使用代码隐藏模型,记住在 Control 指令中包含 ClassName 特性(这样控件就是强类型的,可以访问到控件的属性和方法)。如果正在使用代码隐藏模型,就需要修改代码隐藏类以便它从 UserControl 而不是 Page 继承。
- 把文件扩展名从 .aspx 更改为 .ascx
处理事件
下面这个示例创建一个简单的 TimeDisplay 用户控件,它有几个事件处理逻辑,这个用户控件封装了一个 LinkButton 控件:
- <%@ Control Language="C#" AutoEventWireup="true" CodeFile="TimeDisplay.ascx.cs" Inherits="Chapter15_TimeDisplay" %>
- <asp:LinkButton ID="lnkTime" runat="server" OnClick="lnkTime_Click"></asp:LinkButton>
- public partial class Chapter15_TimeDisplay : System.Web.UI.UserControl
- {
- protected void Page_Load(object sender, EventArgs e)
- {
- if (!Page.IsPostBack)
- {
- RefreshTime();
- }
- }
- protected void lnkTime_Click(object sender, EventArgs e)
- {
- RefreshTime();
- }
- public void RefreshTime()
- {
- lnkTime.Text = DateTime.Now.ToLongTimeString();
- }
- }
添加属性
目前你能在 Web 窗体里做的只是调用 RefreshTime() 这个公共的方法来更新显示。为了让用户控件更具灵活性和可重用性,开发人员通常会为用户控件添加属性。修改后用户控件代码如下(新增 Format 属性、修改了 RefreshTime 方法):
- public string Format { get; set; }
- public void RefreshTime()
- {
- if (Format == null)
- {
- lnkTime.Text = DateTime.Now.ToLongTimeString();
- }
- else
- {
- lnkTime.Text = DateTime.Now.ToString(Format);
- }
- }
Web 页面的代码如下:
- <%@ Page Language="C#" AutoEventWireup="true" CodeFile="TimeDisplayHost.aspx.cs"
- Inherits="Chapter15_TimeDisplayHost" %>
- <%@ Register Src="~/Chapter15/TimeDisplay.ascx" TagPrefix="apress" TagName="TimeDisplay" %>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <apress:TimeDisplay ID="TimeDisplay1" runat="server" Format="dddd,dd MMMM yyyy HH:mm:ss tt (GMT z)" />
- <hr />
- <apress:TimeDisplay ID="TimeDisplay2" runat="server" />
- </div>
- </form>
- </body>
- </html>
- public partial class Chapter15_TimeDisplayHost : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
- if (Page.IsPostBack)
- {
- TimeDisplay2.Format = "dddd,dd MMMM yyyy HH:mm:ss tt (GMT z)";
- }
- }
- }
初次加载: 点击后:
给用户控件添加属性时,理解页面事件发生的顺序就变的很重要了,一般按如下顺序初始化页面:
- 请求页面。
- 创建用户控件。如果变量有默认值,或者在类的构造函数里执行了初始化,那么此时会用到它们。
- 如果在用户标签里设置了任意属性,会用到它们。
- 执行页面的 Page.Load 事件,准备初始化用户控件。
- 执行用户控件的 Page.Load 事件,准备初始化用户控件。
理解了这个顺序后你会明白,不应该在 用户控件的 Page.Load 事件里执行用户控件初始化,因为它可能会覆盖客户端指定的设置。
使用自定义对象
很多用户控件是为通过更高层控件模型对通用场景细节进行抽象而设计的(例如地址信息,你可能会组合几个文本框到一个更高层次的 AddressInout 控件)。为这类控件建模的时候,需要使用比单独的字符串和数值更复杂的数据。通常,你会创建一个自定义类,它是为网页和用户控件之间的通信而特别设计的。
为了说明这一思想,下面的示例开发了一个 LinkTable 控件,它在一个格式化表里呈现一组超链接:
- /// <summary>
- /// 为了支持用户控件,使用这个自定义类定义每个链接所需的信息
- /// </summary>
- public class LinkTableItem
- {
- public string Text { get; set; }
- public string Url { get; set; }
- public LinkTableItem() { }
- public LinkTableItem(string text, string url)
- {
- this.Text = text;
- this.Url = url;
- }
- }
接下来考虑 LinkTable 用户控件的代码隐藏类。它定义了 Title 属性,还定义了 Items 集合用来接受 LinkTableItem 对象数组:
- public partial class Chapter15_LinkTable : System.Web.UI.UserControl
- {
- public string Title
- {
- get { return lblTitle.Text; }
- set { lblTitle.Text = value; }
- }
- private LinkTableItem[] items;
- public LinkTableItem[] Items
- {
- get { return items; }
- set
- {
- items = value;
- this.gridLinkList.DataSource = items;
- this.gridLinkList.DataBind();
- }
- }
- }
控件自身使用数据绑定呈现它大部分用户界面。每当 Items 属性被设置或变更时,LinkTable 里的 GridView 就会重新绑定到条目集合:
- <%@ Control Language="C#" AutoEventWireup="true" CodeFile="LinkTable.ascx.cs" Inherits="Chapter15_LinkTable" %>
- <table border="1" cellpadding="2">
- <tr>
- <td>
- <asp:Label ID="lblTitle" runat="server" ForeColor="#C00000" Font-Bold="true" Font-Names="Verdana"
- Font-Size="Small">[Title Goes Here]</asp:Label>
- </td>
- </tr>
- <tr>
- <td>
- <asp:GridView ID="gridLinkList" runat="server" AutoGenerateColumns="false" ShowHeader="false"
- GridLines="None">
- <Columns>
- <asp:TemplateField>
- <ItemTemplate>
- <img height="23" src="exclaim.gif" alt="Menu Item" style="vertical-align: middle" />
- <asp:HyperLink ID="lnk" runat="server" NavigateUrl='<%# DataBinder.Eval(Container.DataItem,"Url") %>'
- Font-Names="Verdana" Font-Size="XX-Small" ForeColor="#0000cd">
- <%
- 1: # DataBinder.Eval(Container.DataItem,"Text")
- %>
- </asp:HyperLink>
- </ItemTemplate>
- </asp:TemplateField>
- </Columns>
- </asp:GridView>
- </td>
- </tr>
- </table>
最后,这是一个典型的网页代码,用它定义一个链接列表,然后将列表绑定到 LinkTable 用户控件来显示它:
- public partial class Chapter15_LinkTableTest : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
- LinkTable1.Title = "A List of Links";
- LinkTableItem[] items = new LinkTableItem[3];
- items[0] = new LinkTableItem("Apress", "http://www.apress.com");
- items[1] = new LinkTableItem("Microsoft", "http://www.microsoft.com");
- items[2] = new LinkTableItem("ProseTech", "http://www.prosetech.com");
- LinkTable1.Items = items;
- }
- }
添加事件
用户控件和网页交互的另一种方式要借助事件。通过方法和属性,用户控件响应网页代码带来的变化。使用事件时,刚好相反,用户控件通知网页发生了某个活动,然后网页代码作出响应。
用户执行某个活动后,比如单击某个按钮或者从列表框里选择了某个选项,用户控件就会截获一个 Web 控件事件并产生一个新的,更高层次的事件通知网页。
定义事件必须使用一个 event 关键字以及一个代表事件签名的委托。.NET 事件标准指定了每个事件必须有2个参数,第一个参数是引发事件的控件的引用,第二个参数包含额外的信息(这些信息包含在一个继承自 System.EventArgs 类的自定义类中)。
下一个示例修改 LinkTable 以便用户单击某项时通知用户,这样网页就可以根据单击的项作出不同反应。在 LinkTable 示例里有必要传递“哪一个链接被单击了”这样的基本信息,为了支持这一设计,我们创建一个自定义的 EventArgs 对象,加入了一个只读属性,返回相应的 LinkTableItem 对象:
- public class LinkTableEventArgs:EventArgs
- {
- private LinkTableItem selectedItem;
- public LinkTableItem SelectedItem
- {
- get { return selectedItem; }
- }
- public bool Cancel { get; set; }
- public LinkTableEventArgs(LinkTableItem item)
- {
- this.selectedItem = item;
- }
- }
- public delegate void LinkClickedEventHandler(object sender,LinkTableEventArgs e);
接着,LinkTable 类使用 LinkClickedEventHandler 定义一个事件:
- public event LinkClickedEventHandler LinkClicked;
为了截获服务器端的单击,需要用 LinkButton 控件替换 HyperLink 控件,因为前者才会引发一个服务器事件,后者只是呈现为一个锚标记:
- <ItemTemplate>
- <img height="23" src="exclaim.gif" alt="Menu Item" style="vertical-align: middle" />
- <asp:LinkButton ID="lnk" runat="server" Font-Names="Verdana" Font-Size="XX-Small"
- ForeColor="#0000cd" CommandName="LinkClick"
- CommandArgument='<%# DataBinder.Eval(Container.DataItem,"Url") %>'
- Text='<%# DataBinder.Eval(Container.DataItem,"Text") %>'>
- </asp:LinkButton>
- </ItemTemplate>
然后,通过处理 GridView.RowCommand 事件截获服务器端的单击事件,编写把它作为 LinkClicked 事件传送给网页的事件处理程序:
- public event LinkClickedEventHandler LinkClicked;
- protected void gridLinkList_RowCommand(object sender, GridViewCommandEventArgs e)
- {
- if (LinkClicked != null)
- {
- LinkButton link = e.CommandSource as LinkButton;
- LinkTableItem item = new LinkTableItem(link.Text, link.CommandArgument);
- LinkTableEventArgs args = new LinkTableEventArgs(item);
- LinkClicked(this, args);
- // 引用类型的传递,修改结果会得以保留
- // 因此后续可接着判断 Cancel 的值确定行为
- if (!args.Cancel)
- {
- Response.Redirect(item.Url);
- }
- }
- }
接着在 Web 页面上对这个事件进行注册,由于用户控件没有提供设计时支持,你必须手工编写事件处理程序及进行注册:
- protected void LinkClicked(object sender, LinkTableEventArgs e)
- {
- lblInfo.Text = "You clicked '" + e.SelectedItem.Text
- + "' but this page not to direct you to '" + e.SelectedItem.Url + "'.";
- e.Cancel = true;
- }
可以在 Page.Load 里注册这个事件:
- LinkTable1.LinkClicked += LinkClicked;
也可以在源页面的控件标签里关联(必须加上 On 前缀):
- <apress:LinkTable ID="LinkTable1" runat="server" OnLinkClicked="LinkClicked" />
公开内部 Web 控件
用户控件包含的控件只能够被用户控件自身访问。通常这正是你希望的行为,它意味着用户控件可以加入公开特定细节的公有属性而不会让网页任意干预控件内所有的事,否则往往会带来无效或不稳定的变化。
例如,如果想调整 LinkButton 控件的前景色,那可以给用户控件添加 ForeColor 属性:
- public Color ForeColor
- {
- get { return lnkTime.ForeColor; }
- set { lnkTime.ForeColor = value; }
- }
如果要公开一大堆属性,这个工作就变的很乏味了,这时应考虑公开整个对象(需要使用只读属性,网页不可能用一个其他东西取代控件):
- public LinkButton InnerLink
- {
- get { return lnkTime; }
- }
宿主页面设置前景色的代码就变成了:
- TimeDisplay.InnerLink.ForeColor = System.Drawing.Color.Green;
公开整个内部控件对象时,网页可以调用控件所有方法可以接收它所有的事件,这种方式带来了无限的灵活性,但同时限制了代码的重用性,它还增大了网页与用户控件当前实现的内部细节紧密耦合的可能性。
作为一个基本规则,创建专门的方法、事件、属性,只公开必要的功能。这总会更好一些,不会为制造混乱提供机会。
动态加载用户控件
除了在页面注册用户控件类型并添加相应的控件标签把用户控件添加到页面上,还可以动态的创建用户控件,需要做如下这些事情:
- 在 Page.Load 事件发生时添加用户控件(这样用户控件可以正确重置它的状态并接收回发事件)。
- 使用容器控件和 PlaceHolder 控件来确保用户控件在你希望的位置结束。
- 设置 ID 属性给用户控件一个唯一的名称。在需要的时候可以借助 Page.FindControl()获取对控件的引用。
- 普通控件可以直接创建,而用户控件不可以直接创建(因为用户控件并非完全基于代码,它们还需要 .ascx 文件里定义的控件标签,ASP.NET 必须处理这个文件并初始化相应的子控件对象)。
- 必须调用 Page.LoadControl()并传递 .ascx 文件名,此方法返回一个 UserControl 对象,可以把它添加到页面上并把它转换为特定类型。
- protected void Page_Load(object sender, EventArgs e)
- {
- TimeDisplay ctrl = Page.LoadControl("TimeDisplay.ascx") as TimeDisplay;
- PlaceHolder1.Controls.Add(ctrl);
- }
除了一些微不足道的琐碎细节外,和用户控件一起使用时,动态加载是一项非常强大的技术,它常用于创建高度可配置的门户框架。
门户框架
创建一个完整的门户框架需要大量的公式化代码,但是你可以从一个简单的示例中看出最重要的规则。
- protected void Page_Load(object sender, EventArgs e)
- {
- string ctrlName = DropDownList1.SelectedItem.Value;
- if (ctrlName.EndsWith(".ascx"))
- {
- PlaceHolder1.Controls.Add(Page.LoadControl(ctrlName));
- }
- Label1.Text = "Loaded..." + ctrlName;
- }
动态加载用户控件的话,Web 页面还是需要注册用户控件的,勿忘!
- <%@ Page Language="C#" AutoEventWireup="true" CodeFile="DynamicUserControl.aspx.cs"
- Inherits="Chapter15_DynamicUserControl" %>
- <%@ Register Src="~/Chapter15/TimeDisplay.ascx" TagName="TimeDisplay" TagPrefix="apress" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <asp:Panel ID="Panel1" runat="server" Width="600" BackColor="Silver">
- <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" Style="margin-right: 23px">
- <asp:ListItem Value="(None)">(None)</asp:ListItem>
- <asp:ListItem Value="TimeDisplay.ascx">TimeDisplay</asp:ListItem>
- </asp:DropDownList>
- <br />
- <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
- <br />
- <br />
- <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
- </asp:Panel>
- </div>
- </form>
- </body>
- </html>
由于列表默认选项是 None,因此 TimeDisplay 控件只在页面至少回发一次后才会被加载。因此它是不会显示时间的。可以通过多种方式解决这一问题,例如加载控件时从 Web 页面调用 RefreshTime():
- TimeDisplay time = Page.LoadControl(ctrlName) as TimeDisplay;
- time.RefreshTime();
- PlaceHolder1.Controls.Add(time);
一个更好的办法是为用户控件创建一个定义特定方法(如 InitializeControl())的接口。这样,你就可以通过一致的方式初始化任意控件了,多数门户框架使用接口提供这种标准化。
局部页面缓存
输出缓存的一个缺点是它工作在要么全有要么全无的模式。如果你需要动态的缓存页面的某些部分,它就不再有效。例如,你会希望缓存一个从数据库获得的记录填充表格,从而减少与数据库间的往返,不过在这同时你还需要获得页面其他部分最新的输出。
如果遇到的是这种情形,用户控件完全能够满足你的要求,因为它们可以缓存自己的输出。这个功能叫部分缓存,或者片段缓存。
把下面这行加入到用户控件的 .ascx 部分,比如 TimeDisplay:
- <%@ OutputCache Duration="10" VaryByParam="None" %>
VaryByParam 特性和页面缓存一样,允许在 URL 改变时根据查询字符串参数缓存不同的 HTML 输出。
使用局部缓存时有一点要注意,缓存用户控件后,它本质上变成了一段静态的 HTML 代码,这样,网页代码不可以再访问用户控件对象。
VaryByControl
如果用户控件里有输入控件,就很难使用缓存。如果输入控件的内容会影响用户控件要显示的缓存内容,就会发生问题。无论用户输入了什么,都只能使用同样的用户控件副本(类似的问题也存在于网页,这就是缓存含有输入控件的页面通常没有意义的原因)。
VaryByControl 属性解决了这一问题。VaryByControl 接受一个用分号分隔的控件名称字符串,用于缓存不同的内容(与 VaryByParameter 根据查询字符串值缓存不同的内容相同)。
- <%@ Control Language="C#" AutoEventWireup="true" CodeFile="VaryingDate.ascx.cs" Inherits="VaryingDate" %>
- <%@ OutputCache Duration="30" VaryByControl="lstMode" %>
- <asp:DropDownList ID="lstMode" runat="server" Width="187px">
- <asp:ListItem>Large</asp:ListItem>
- <asp:ListItem>Small</asp:ListItem>
- <asp:ListItem>Medium</asp:ListItem>
- </asp:DropDownList>
- <br />
- <asp:Button ID="Button1" Text="Submit" runat="server" />
- <br />
- <br />
- Control generated at:<br />
- <asp:Label ID="TimeMsg" runat="server" />
- protected void Page_Load(object sender, EventArgs e)
- {
- switch (lstMode.SelectedIndex)
- {
- case 0:
- TimeMsg.Font.Size = FontUnit.Large;
- break;
- case 1:
- TimeMsg.Font.Size = FontUnit.Small;
- break;
- case 2:
- TimeMsg.Font.Size = FontUnit.Medium;
- break;
- }
- TimeMsg.Text = DateTime.Now.ToString("F");
- }
运行这个示例你会看到,ASP.NET 确实为列表中的每个选项单独进行了缓存。
共享缓存控件
如果在 10 个不同的页面中使用同一个用户控件,ASP.NET 将会缓存该控件的 10 个独立版本,这样用户控件被缓存前,每个页面第一次执行时都可以自定义用户控件。
不过在很多情况下需要在多个页面上重用相同的用户控件,但不需要任何的自定义。此时,ASP.NET 共享控件的缓存副本可以节省内存。ASP.NET 通过 OutputCache 指令的 Shared 属性启用共享。Shared 属性只在你把它应用到用户控件而不是 Web 窗体的指令时才起作用:
- <%@ OutputCache Duration="10" VaryByParam="None" Shared="true" %>
还可以在用户控件的类声明前添加 PartialCaching 特性实现等效的结果:
- [PartialCaching(10, null, null, null, true)]
- public partial class VaryingDate : System.Web.UI.UserControl
- {...}
这里的 null 分别代表:VaryByParameter、VaryByControl、VaryByCustom 。
(九)ASP.NET自定义用户控件(2)的更多相关文章
- (八)ASP.NET自定义用户控件(1)
http://blog.csdn.net/laodao1/article/details/5897366 ASP.NET自定义控件组件开发 第一章:从一个简单的控件谈起 起始开发ASP.NET自定义控 ...
- (十)ASP.NET自定义用户控件(3)
using HX.DHL.EIP.Services.Def.Localization; using HX.DHL.EIP.Web.Framework; using System; using Syst ...
- Windows phone 自定义用户控件(UserControl)——ColorPicker
编码前 学习Windows phone自定义用户控件,在<WPF编程宝典>学习的小例子.并根据windows phone稍微的不同,做了点修改.ColorPicker(颜色拾取器):拥有三 ...
- 2018-8-10-win10-uwp-验证输入-自定义用户控件
title author date CreateTime categories win10 uwp 验证输入 自定义用户控件 lindexi 2018-08-10 19:16:51 +0800 201 ...
- 在Winform界面使用自定义用户控件及TabelPanel和StackPanel布局控件
在很多时候,我们做一些非常规化的界面的时候,往往需要创建一些用户控件,在其中绘制好一些基础的界面块,作为后续重复使用的一个单元,用户控件同时也可以封装处理一些简单的逻辑.在开发Winform各种类型项 ...
- asp.net读取用户控件,自定义加载用户控件
1.自定义加载用户控件 ceshi.aspx页面 <html> <body> <div id="divControls" runat="se ...
- 浅尝辄止WPF自定义用户控件(实现颜色调制器)
主要利用用户控件实现一个自定义的颜色调制控件,实现一个小小的功能,具体实现界面如下. 首先自己新建一个wpf的用户控件类,我就放在我的wpf项目的一个文件夹下面,因为是一个很小的东西,所以就没有用mv ...
- C# 自定义用户控件
上篇:控件制作 本例是制作一个简单的自定义控件,然后用一个简单的测试程序,对于初学者来说,本例子比较简单,只能起到抛石引玉的效果.我也是在学习当中,今后会将自己所学的逐步写出来和大家交流共享. 第一步 ...
- ASP.NET的用户控件
本文介绍如何在ASP.NET中创建用户控件,控件属性的动态修改以及控件的事件出发机制. 简介ASP.NET的服务端控件使得Web开发工作变得更为简单,功能更为强大.我们介绍过如何在ASP.NET页面中 ...
随机推荐
- Python python 基本语法
程序1 def buildConnectionString(params): """Build a connection string from a dictionary ...
- 02.Redis主从集群的Sentinel配置
1.集群环境 1.Linux服务器列表 使用4台CentOS Linux服务器搭建环境,其IP地址如下: 192.168.110.100 192.168.110.101 192.168.110.102 ...
- ionic 实现双击返回键退出应用功能
ionic 实现双击返回键退出应用功能 keywords cordova,ngcordova,phonegap,ionic,双击,返回键,退出 例子 准备Toast插件,提示用,用户体验好点,不是必须 ...
- UVA 10002 Center of Masses
题目链接:http://acm.uva.es/local/online_judge/search_uva.html Problem:Find out the center of masses of a ...
- BZOJ3170: [Tjoi 2013]松鼠聚会
3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 531 Solved: 249[Submit][Statu ...
- 【CoreData】parent-child关系ManagedObjectContext应用
当我们一开始使用CoreData框架和唯一的MOC进行应用的数据持久化的时候,如果创建项目的时候选择了“使用CoreData”,这会是XCode自动生成的模板代码的样子. 同时,配合NSFetched ...
- 数据类型的处理(提取自FMDB)
if ((!obj) || ((NSNull *)obj == [NSNull null])) { sqlite3_bind_null(pStmt, idx); } // FIXME - someda ...
- apple 官方文档 Push Notification Programming
iOS Developer LibraryDeveloper Search Local and Push Notification Programming Guide PDF Table of Con ...
- 【bzoj1012】[JSOI2008]最大数maxnumber
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8339 Solved: 3624[Submi ...
- 深入理解python之self
首先明确的是self只有在类的方法中才会有,独立的函数或方法是不必带有self的.self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数. self名称不是必须的,在python中self ...