ASP.NET用戶控件技術(shù)
什么是用戶控件(User Controls)?
為了能更好的理解用戶控件的重要性,我們先來(lái)看看一段小小的“歷史”。在以前的ASP當(dāng)中,可重用的技術(shù)實(shí)現(xiàn)選擇是相當(dāng)受限制的。許多的開(kāi)發(fā)者一般都是借助將公共的常用的子過(guò)程放到那些包含文件當(dāng)中的做法來(lái)實(shí)現(xiàn)一定的所謂代碼重用的。比如,如我們想要在許多的ASP頁(yè)面當(dāng)中現(xiàn)實(shí)一個(gè)下拉列表框,我會(huì)在一個(gè)包含文件當(dāng)中建立一個(gè)函數(shù),樣子如下所示:
Function GetListBox(asSelectedItem)
'為HTML的選擇控件建立字符串
'返回這個(gè)字符串
End Function
當(dāng)然,這樣的做法的確在一定程度上做到了重用,但是為了能做到更加通用性,你不得不要增加更多的參數(shù)。為了使得類(lèi)似上面的你需要整理的代碼得以正常工作是困難的,因?yàn)橐_(dá)到提供它的通用性(可重用性),你大概不得不去修改這些已經(jīng)存在的代碼,以便使得他們也能在新的環(huán)境下正常工作。
IIS5中的VBScript5.0增加了建立類(lèi)的功能。這就使得我們可以通過(guò)一個(gè)較多面向?qū)ο蟮姆绞絹?lái)實(shí)現(xiàn)可重用的代碼。
Class ComboBox
Property Let ControlName(vData)
.
End Property
End Class
這樣做會(huì)稍微好一些,但是開(kāi)發(fā)者仍舊需要被迫去編寫(xiě)那些函數(shù),以便返回HTML代碼。而且,他也沒(méi)有能力操縱那些類(lèi)的實(shí)例對(duì)象的事件。為了能做到操作事件,開(kāi)發(fā)者不得不建立一些COM組件,而后者則增加了應(yīng)用程序的額外的復(fù)雜度。
有了ASP.NET,我們擁有了一個(gè)新的簡(jiǎn)單的工具來(lái)編寫(xiě)可重用的代碼—用戶控件。用戶控件(也叫pagelets)提供了這樣一種機(jī)制,他使得我們可以建立能夠非常容易的被ASP.NET頁(yè)面使用或者重新利用的代碼部件。一個(gè)用戶控件也是一個(gè)簡(jiǎn)單的ASP.NET頁(yè)面,不過(guò)它可以被另外一個(gè)ASP.NET頁(yè)面包含進(jìn)去。在你的ASP.NET應(yīng)用程序當(dāng)中使用用戶控件的一個(gè)主要的優(yōu)點(diǎn)是用戶控件的支持一個(gè)完全面向?qū)ο蟮哪J?,使得你有能力去捕獲事件。而且,用戶控件支持你使用一種語(yǔ)言編寫(xiě)ASP.NET頁(yè)面其中的一部分代碼,而使用另外的一種語(yǔ)言編寫(xiě)ASP.NET頁(yè)面另外一部分代碼,因?yàn)槊恳粋€(gè)用戶控件可以使用和主頁(yè)面不同的語(yǔ)言來(lái)編寫(xiě)。
建立一個(gè)用戶控件
在建立你自己的用戶控件之前,你也許想知道在你的web頁(yè)面中哪些可見(jiàn)的對(duì)象是能夠重用的好的候選者。能可能的是,你將會(huì)在你的站點(diǎn)上的不止一個(gè)頁(yè)面上需要使用融合的用戶控件。一旦你開(kāi)始不斷的思考你的控件的結(jié)構(gòu),你就已經(jīng)做好的開(kāi)始的準(zhǔn)備。在我們的例子當(dāng)中,我們將要建立一個(gè)簡(jiǎn)單的搜索的控件,用來(lái)搜索SQL Server2000中的數(shù)據(jù)庫(kù)Northwind。我們的搜索控件可以使得開(kāi)發(fā)者快速的為一個(gè)web頁(yè)面增加搜索能力。
建立用戶控件的第一步是建立一個(gè).ascx文件。這是用戶控件需要的文件擴(kuò)展名。在一個(gè)一個(gè).ascx文件中不能包含head,form,或者body標(biāo)簽,因?yàn)榘?ascx文件的.aspx文件已經(jīng)包含了這些標(biāo)簽。一個(gè).ascx文件只能包含方法,函數(shù),以及和用戶控件相關(guān)的內(nèi)同。
在建立一個(gè).ascx文件之后,我們想要為用戶控件增加一些可視的代碼。在一個(gè)用戶控件當(dāng)中可以包含所有的web控件。在我們的例子當(dāng)中,搜索控件需要擁有一個(gè)標(biāo)簽,一個(gè)文本框以及一個(gè)按鈕。我們首先加入這些web控件,因?yàn)槲覀兊恼麄€(gè)代碼當(dāng)中會(huì)涉及到這些對(duì)象。下面是具體的代碼:
在用戶控件中有一件很酷的事情是,你可以定義你自己的屬性。在我們的例子當(dāng)中,我們會(huì)定義如下屬性:
。LabelText—描述顯示給用戶的搜索條件
。ConnectiongString---用來(lái)聯(lián)接到數(shù)據(jù)庫(kù)的連接字符串
。ResultSetView—包含了搜索結(jié)果的數(shù)據(jù)記錄集
。TableName—要搜索的數(shù)據(jù)庫(kù)table名稱(chēng)
。Condition—需要搜索的table的列的名稱(chēng)
為了建立這些屬性,我們使用一些聯(lián)合起來(lái)的get和set方法來(lái)同屬性結(jié)合起來(lái)。在做這些工作之前,我們需要首先決定一個(gè)屬性是否需要允許讀,寫(xiě),還是兩者都需要。對(duì)于只需要讀的屬性,我們將會(huì)使用ReadOnly關(guān)鍵字來(lái)限定屬性的聲明,并且僅僅包含了get方法。我們的ResultSetView屬性是一個(gè)只讀的屬性,因此它的相關(guān)代碼看起來(lái)如下:
'這是一個(gè)只讀的屬性
Public ReadOnly Property ResultSetView as dataView
Get
'設(shè)置返回屬性地值
ResultSetView = dsData.tables("BookTitles").defaultview
End Get
End Property
對(duì)于只需要寫(xiě)的屬性,我們將會(huì)使用WriteOnly關(guān)鍵字來(lái)限定屬性的聲明,并且僅僅包含了set方法。我們的TableName屬性是一個(gè)只寫(xiě)屬性,因此它的相關(guān)代碼看起來(lái)如下:
'This write only attribute identifies which table will be searched
Public WriteOnly Property TableName as string
Set
'設(shè)置表的名稱(chēng)
strTableName = Value
End Set
End Property
對(duì)于那些既能讀也能寫(xiě)的屬性,在定義的時(shí)候就不需要加以限定了;并且同時(shí)包含了Get和Set方法。一旦這個(gè)屬性被建立,.aspx文件就可以讀取或者設(shè)置這些屬性,使得用戶控件可以適應(yīng)一個(gè)或者多個(gè)用途了。
在用戶控件當(dāng)中,和定義不同的屬性相結(jié)合,你也需要定義任意的方法,這些方法可以被用戶控件初始化。這些屬性和方法定義了用戶控件的功能。在我們的例子當(dāng)中使用的是search方法。這個(gè)方法讀取各個(gè)用戶定義在.aspx文件中的控件屬性,并且返回一個(gè)搜索的結(jié)果記錄集。所有的操縱數(shù)據(jù)庫(kù)的代碼都在這個(gè)方法中了:建立SQL語(yǔ)句,打開(kāi)數(shù)據(jù)庫(kù)聯(lián)接,并且從數(shù)據(jù)庫(kù)中返回一個(gè)結(jié)果。
'這個(gè)程序依照屬性的值來(lái)操縱一個(gè)數(shù)據(jù)庫(kù)
Public Sub Search(sender As Object , e As System.EventArgs)
Dim cnConnection As SQLConnection
Dim cmdCommand As SQLDataSetCommand
Dim strSearchString As String
Dim strSQL As String
'如果用戶在搜索框中輸入了條件
If txtSearch.Text <> "" Then
'過(guò)濾掉字符的前后空格
strSearchString = trim$(txtSearch.Text)
End If
'建立我們的SQL語(yǔ)句
strSQL = "Select * " & _
"FROM " & strTableName & _
" Where " & strConditionField & " LIKE '" & _
trSearchString & "%'"
'如果聯(lián)接屬性被設(shè)置了
If strConnection <> "" Then
'建立數(shù)據(jù)庫(kù)聯(lián)接
cnConnection = New SQLConnection(strConnection)
'打開(kāi)數(shù)據(jù)庫(kù)聯(lián)接
cnConnection.open()
'為搜索建立一個(gè)新的command對(duì)象
cmdCommand = New SQLDataSetCommand(strSQL, cnConnection)
'建立一個(gè)新的DataSet對(duì)象
dsData = New DataSet()
'填充dataset對(duì)象
cmdCommand.FillDataSet(dsData, "BookTitles")
End If
End Sub
一旦你在你的用戶控件當(dāng)中添加了屬性和方法,控件的開(kāi)發(fā)也就大致完成了。
現(xiàn)在我們對(duì)一個(gè)用戶控件是如何建立的有了一個(gè)認(rèn)識(shí),讓我們來(lái)看看用戶控件是如何工作的。下面是我們的用戶控件被包含在一個(gè)form當(dāng)中的時(shí)候看起來(lái)的樣子:
我們的用戶控件將會(huì)放在一個(gè)國(guó)際食物網(wǎng)站的一個(gè)搜索頁(yè)面上。為了建立這個(gè)搜索頁(yè)面,我們先建立一個(gè)空的.aspx文件。我們先安排好所有的圖片和布局,之后加入我們的用戶控件。
為了能夠在一個(gè).aspx頁(yè)面當(dāng)中使用這個(gè)新的用戶控件,你必須首先初始化@Register指令。當(dāng)使用這個(gè)標(biāo)簽的時(shí)候,你必須定義標(biāo)簽前綴,標(biāo)簽名字以及指定用戶控件所在的源文件。
TagPrefix定義了我們使用這個(gè)用戶控件的時(shí)候想要用的名稱(chēng)空間。TagName定義了這個(gè)用戶控件的實(shí)際名稱(chēng)。你可以任意的命名你的控件,這個(gè)名字將會(huì)用在頁(yè)面上面標(biāo)示用戶控件。
當(dāng)你加入一個(gè)用戶控件到一個(gè).aspx頁(yè)面的時(shí)候,相應(yīng)的語(yǔ)法同加入一個(gè)web控件類(lèi)似。你首先使用標(biāo)簽前綴和標(biāo)簽名稱(chēng)來(lái)標(biāo)示用戶控件:
現(xiàn)在我們?cè)陧?yè)面上面有了這個(gè)空間,我們可以設(shè)置標(biāo)準(zhǔn)的runat和id屬性,以及設(shè)置我們以前建立控件的時(shí)候建立的各個(gè)自己定義的屬性。有兩種方法來(lái)修改這些用戶控件的屬性(就像針對(duì)一個(gè)ASP.NET的web控件那樣)。一種方法是在你的web頁(yè)面當(dāng)中引用這個(gè)用戶控件的時(shí)候明確的設(shè)置它的各個(gè)屬性的值。在我們的例子當(dāng)中,我們?cè)O(shè)置LabelText屬性為“Product Name”,因?yàn)槲覀兊乃阉魇轻槍?duì)產(chǎn)品名稱(chēng)來(lái)講的。
另外一種方法是在一個(gè).aspx文件的page_load事件中設(shè)置這些用戶控件的屬性。針對(duì)我們的例子,我們?cè)趐age_load事件當(dāng)中設(shè)置ConnectionString,TableName,ConditionField屬性。我們需要搜索的是數(shù)據(jù)庫(kù)Northwind中Product表的ProductName字段。
Sub page_load(objSource as Object, objArgs as eventArgs)
Dim htConfig As HashTable
'設(shè)置一個(gè)對(duì)Config.web文件中AppSettings節(jié)點(diǎn)的應(yīng)用
htConfig = Context.GetConfig("appsettings")
'設(shè)置用戶控件的連接字符串
userControl.ConnectionString=(htConfig("MyConn"))
'設(shè)置我們要搜索的表的名稱(chēng)
userControl.TableName="Product"
'設(shè)置我們要搜索的字段名稱(chēng)
userControl.ConditionField="ProductName"
對(duì)于我們的web站點(diǎn),我們將數(shù)據(jù)庫(kù)的連接字符串存放在Config.web文件當(dāng)中的叫做appsettings中的區(qū)域中。(如果要使用下面的代碼,請(qǐng)將server修改成你實(shí)際的server名字)
下面是我們的.aspx文件第一次看起來(lái)的樣子:
現(xiàn)在我們需要加入代碼來(lái)調(diào)用我們的用戶控件中的search方法。我們編寫(xiě)這個(gè)用戶控件的例子的目的是為了實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的簡(jiǎn)單搜索以及返回搜索的結(jié)果。為了做到這些,我們有兩個(gè)選擇,我們要么在我們的用戶控件當(dāng)中將我們的結(jié)果放到我們的結(jié)果控件(在這里,一般是一個(gè)DataGrid控件),要么我們將一個(gè)ADO記錄集當(dāng)作一個(gè)屬性返回給開(kāi)發(fā)者,而不必關(guān)心開(kāi)發(fā)者究竟使用什么方法來(lái)顯示他。我們的選擇是通過(guò)一個(gè)屬性返回一個(gè)記錄集結(jié)果,因?yàn)檫@樣做可以使得開(kāi)發(fā)者可以自由的選擇使用什么控件以及采用什么樣的數(shù)據(jù)顯示方式。
然而這個(gè)選擇同時(shí)也帶給了我們一些問(wèn)題。我們可以容易的將結(jié)果當(dāng)作一個(gè)屬性返回并且使用DataSource屬性綁定到一個(gè)DataGrid控件或者其他的控件。但是,我們?nèi)绾尾拍苤烙脩羰欠袷屈c(diǎn)擊了一個(gè)搜索按鈕呢?為了解決這個(gè)問(wèn)題,我們需要在page_load事件中使用Page.IsPostBack這個(gè)屬性。如果一個(gè)頁(yè)面是由于post而重載的話,屬性Page.Ispostback的值等于true。通過(guò)檢測(cè)page.ispostback是否等于true,我們可以決定是否調(diào)用我們的用戶控件中的Search方法,然后將結(jié)果綁定到我們的datagrid。
'檢測(cè)Page.IsPostBack屬性的值
If page.IsPostback = true then
'執(zhí)行搜索的動(dòng)作
userControl.Search(objSource, objArgs)
'將結(jié)果綁定到DataGrid控件上面
grdGrid.datasource = userControl.ResultSetView
'正式綁定數(shù)據(jù)
grdGrid.databind()
End If
End Sub
在某個(gè)人輸入了一個(gè)搜索條件之后并提交我們的.aspx文件之后的顯示頁(yè)面:
現(xiàn)在我們可以同樣的建立另外一個(gè)頁(yè)面以便使用在我們的站點(diǎn)。我們將要建立的這第二個(gè)頁(yè)面同樣執(zhí)行一個(gè)搜索動(dòng)作,但是這次是要在Northwind數(shù)據(jù)庫(kù)的表Company上的CompanyName字段上面進(jìn)行搜索匹配。為了建立這個(gè)頁(yè)面,我們建立一個(gè)新的空白.aspx文件。既然這個(gè)頁(yè)面和我們的產(chǎn)品頁(yè)面類(lèi)似,我們使用相同的布局。我們將要再一次使用搜索用戶控件。
我們?cè)谶@個(gè)頁(yè)面會(huì)將屬性設(shè)置不同的值。聯(lián)接字符串還是保留使用前面同樣的值。我們需要設(shè)置屬性LabelText的值等于Company Name,設(shè)置屬性Table的值等于Company,設(shè)置屬性ConditionField的值等于CompanyName。通過(guò)對(duì)布局和用戶控件的略微改動(dòng),我們就算大致完成了這個(gè)頁(yè)面。對(duì)這個(gè)頁(yè)面來(lái)講,我們只需要很少的代碼,這要好好謝謝用戶控件帶來(lái)的代碼重用了。下面就是我們新的頁(yè)面:
正如你所看到的,用戶控件可以提供一個(gè)簡(jiǎn)便的方法來(lái)實(shí)現(xiàn)代碼的可重用性,而省去了很多不必要的麻煩。將相關(guān)的控件和代碼從一個(gè)ASPX文件移到一個(gè)ASCX文件當(dāng)中是一個(gè)恰當(dāng)?shù)淖龇?,并且只需要較小的修改就可以使得代碼正常的工作了。
局限性?
你也許會(huì)問(wèn)自己:我使用用戶控件不能夠做到什么?使用這個(gè)技術(shù)只存在很少的一些限制。
其中的一個(gè)限制是:用戶控件不支持模版。因此,你不能建立一個(gè)用戶控件來(lái)達(dá)到ASP.NET中提供的Data Repeater控件的功能。
另外的一個(gè)限制是:由于用戶控件必須包含一些靜態(tài)的UI(用戶界面)屬性,所以你不能夠按照你的想法嚴(yán)格的調(diào)整他們。比如,你可能想要建立一個(gè)包含多個(gè)控件的用戶控件,并且允許開(kāi)發(fā)者能夠指定這些控件在頁(yè)面上的顯示順序。上面的想法對(duì)于一個(gè)用戶控件來(lái)說(shuō)是困難的,因?yàn)閁I塊是被靜態(tài)的設(shè)置的。
結(jié)論
用戶控件提供了一個(gè)極好的方法使得你能夠非常容易的在你的ASP.NET頁(yè)面中實(shí)現(xiàn)代碼的重用。將一些在ASP.NET中的代碼拖放到ASCX文件中使得他們能夠被重新利用是個(gè)正確的選擇和做法。
在我們的文章中,我們一同探討了通過(guò)定制的控件實(shí)現(xiàn)代碼在ASP.NET中的重用??啥ㄖ频腁SP.NET控件可以對(duì)可重用代碼提供附加的彈性,正如上面我們已經(jīng)學(xué)到那樣。
- ASP.NET用戶控件如何使用
- ASP.NET動(dòng)態(tài)添加用戶控件的方法
- ASP.NET 頁(yè)面中加添加用戶控件的寫(xiě)法
- ASP.NET 用戶控件的使用介紹
- asp.net 動(dòng)態(tài)添加多個(gè)用戶控件
- asp.net 用戶控件讀取以及賦值
- asp.net 用戶控件中圖片及樣式問(wèn)題
- asp.net動(dòng)態(tài)加載用戶控件,關(guān)于后臺(tái)添加、修改的思考
- ASP.NET動(dòng)態(tài)加載用戶控件的實(shí)現(xiàn)方法
- asp.net動(dòng)態(tài)載入用戶控件的方法
- ASP.NET中使用用戶控件
相關(guān)文章
.Net中如何操作IIS的虛擬目錄原理分析及實(shí)現(xiàn)方案
編程控制IIS實(shí)際上很簡(jiǎn)單,和ASP一樣,.Net中需要使用ADSI來(lái)操作IIS,但是此時(shí)我們不再需要GetObject這個(gè)東東了,因?yàn)镹et為我們提供了更加強(qiáng)大功能的新東東2012-12-12EFCore 通過(guò)實(shí)體Model生成創(chuàng)建SQL Server數(shù)據(jù)庫(kù)表腳本
這篇文章主要介紹了EFCore 通過(guò)實(shí)體Model生成創(chuàng)建SQL Server數(shù)據(jù)庫(kù)表腳本的示例,幫助大家更好的理解和學(xué)習(xí)使用.net框架,感興趣的朋友可以了解下2021-03-03IdentityServer4 QuckStart 授權(quán)與自定義Claims的問(wèn)題
這篇文章主要介紹了IdentityServer4 QuckStart 授權(quán)與自定義Claims的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04asp.net treeview checkbox 相關(guān)問(wèn)題
asp.net treeview checkbox 相關(guān)問(wèn)題,需要的朋友可以看下。2009-06-06asp.net(c#) RSS功能實(shí)現(xiàn)代碼
這兩天一邊從網(wǎng)上找資料,自己再測(cè)試,終于完成本站的RSS功能了!先自我恭喜下!!2008-11-11ASP.NET中repeater嵌套實(shí)現(xiàn)代碼(附源碼)
repeater嵌套經(jīng)常會(huì)在一些特殊效果顯示下會(huì)用到,新手朋友們可以詳細(xì)看下本文,希望對(duì)你有所幫助,代碼很整潔同時(shí)附有源碼2013-03-03jQuery+Asp.Net實(shí)現(xiàn)省市二級(jí)聯(lián)動(dòng)功能的方法
這篇文章主要介紹了jQuery+Asp.Net實(shí)現(xiàn)省市二級(jí)聯(lián)動(dòng)功能的方法,涉及asp.net數(shù)據(jù)庫(kù)讀取與字符串轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下2017-05-05