|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
据说很厉害,甚至可以把C#也干掉^_^,不过也很复杂,本来C++已经够复杂的。有人甚至还提出把这个东东引进标准,我觉得基本上不可能的。ASP.NEToffersapowerfulwaytorenderinformationfromadatabaseorXMLfile:Databinding.However,sometimesyouneedtobeabletoperformthedatabindingforalmostalloftheitemsinthedatasource.Orperhapsyouhavesomespecialformattingorsecondarydatathatyouneedtousewitheachrowinthedatasource,sothatyouneedalittlefinercontroloverhowthedataisboundtothecontrol.Inthesecases,youwilltypicallyneedtohandletheonItemDataBoundevent,whichisfiredforeachitemasitisboundtoyourcontrol.ThisgivesyouaLOTofflexibility,butunfortunatelythecodeisalittlebithairy.Hopefully,havinganexamplewillhelp!Firstofall,letmeexplainthatthisexampleistakenfromaLIVEapplication:myRegularExpressionLibraryoveratmyASP.NETtrainingwebsite,ASPSmith.com.Youcanseeitinactionbyclickinghere.Youllseewhatitisdoinginamoment.
FormyRegularExpressionLibrary,IhadseveralthingsIneededtoadjustbeyondthedefaultdatabindingthatmyDataGridprovided"out-of-the-box".Firstly,Ihadauser_idfieldinmydatathatIwantedtoconverttoalinktoausersemail.Next,IwantedtolimithowmuchoftheDescriptionfieldwasdisplayedonthesearchresultspage,toavoidcausingthepagetogetexcessivelylong(sincetheDescriptionfieldisaTEXTfieldinmydatabase,andcouldthereforebemanymegabyteslong).Lastly,IhadanEditlinkthatallowedtheowneroftheregularexpressiontoeditit,butIdidntwantthattobevisibleexceptifthecurrentuserwastheowneroftheexpression.Letsseehowthiswasdone.First,letstakealookatmy(ratherlengthy)Datagriddeclaration.Theimportantpartislistedinred.
default.aspxexcerpt<asp:DataGridid="dgRegexp"runat="server"AutoGenerateColumns="False"BorderColor="Black"BorderWidth="1"Style="margin-left:20px;"PageSize="5"AllowPaging="True"AllowCustomPaging="True"OnPageIndexChanged="dgRegexp_PageIndexChanged"onItemDataBound="dgRegexp_ItemDataBound"GridLines="Horizontal"PagerStyle-Mode="NumericPages"PagerStyle-HorizontalAlign="Center"PagerStyle-Position="TopAndBottom"PagerStyle-Width="100%"HeaderStyle-BackColor="#CC0000"HeaderStyle-Font-Bold="True"HeaderStyle-Font-Name="Verdana"HeaderStyle-Font-Size="9pt"HeaderStyle-ForeColor="White"ItemStyle-Font-Name="Arial"ItemStyle-Font-Size="8pt"AlternatingItemStyle-BackColor="#DDDDDD">
Thisevent,onItemDataBound,issupportedbyanycontrolthatsupportsdatabinding.YoucanuseitwithDataGrids,DataLists,Repeaters,etc.Inthiscase,Ihavemappedminetothe"dgRegexp_ItemDataBound"eventhandler,whichwelltakealookatnow:
default.aspxexcerptprotectedvoiddgRegexp_ItemDataBound(ObjectSender,DataGridItemEventArgse)
{
//ForItemsandAlternatingItems,
//convertuseridtoemaillink
//truncatedescription
//hideeditlinkifnotowner
if(e.Item.ItemType==ListItemType.Item||e.Item.ItemType==ListItemType.AlternatingItem)
{
Trace.Write("ItemDataBound",e.Item.DataItem.GetType().ToString());
intuser_id=Int32.Parse(((System.Data.Common.DbDataRecord)e.Item.DataItem)["user_id"].ToString());
Trace.Write("ItemDataBound","user_id:"+user_id.ToString());
ASPAlliance.DAL.UserDetailsobjUser=ASPAlliance.DAL.User.getUserDetails(user_id);
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).Text=
objUser.first_name+""+objUser.last_name+"("+objUser.email+")";
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).NavigateUrl="mailto:"+objUser.email;
Trace.Write("ItemDataBound","myuser.Text:"+((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).Text);
Stringdesc=((System.Data.Common.DbDataRecord)e.Item.DataItem)["description"].ToString();
if(desc.Length>100)
{desc=desc.Substring(0,99);
desc+="...";
}
((System.Web.UI.WebControls.Label)e.Item.FindControl("description")).Text=desc;
ASPAlliance.DAL.Securitysec=newASPAlliance.DAL.Security(this.Request);
if((sec.user_id==0)||(sec.user_id!=user_id)||(!sec.isAuthenticated))
{
((System.Web.UI.HtmlControls.HtmlTableCell)e.Item.FindControl("editTD")).Visible=false;
}}}}
Ok,nowthatswhatIcallanexample!Noneofthatwussylittle"justfordemonstration"threelinesofcodestuffforus.No,weregoingtogoalloutandshowyousomethingbiganduglythatactuallysitsonaproductionsite.Butdontfear,itwillallbecleartoyouinamoment,ifitisntalready(evenifyouonlyknowVB).Letsbreakthisdown.
Thefirst6linesdeclareourmethodandthrowinsomecomments.AsIsaid,IbasicallyhavethreethingsIwanttodohere:
Convertuseridtoanemaillink
TruncatetheDescriptionfield
HidetheEditlinkifcurrentuserisnottheowner
Theonlythingyoureallyneedtowatchhereistomakesurethatyoursecondparameterstypeiscorrectforthecontrolyouareusing.Thisisprettyself-explanatory,butifyoucantfigureitout,youcanalwayslookatthedefinitionoftheparticularcontrolyouareusingintheClassBrowser.ForyouVB.NETusers,justconvert"//"toasinglequote,getridofthe{andswitchtheparameterstothetypeisfollowingthenameandhas"As"infrontofit.
Next,weneedtomakesureweredealingwiththecorrectitemtype.Sincethiseventisraisedforeveryitemintheboundcontrol,includingItems,AlternatingItems,Separators,Headers,Footers,etc.(completelist),weneedtospecifywhichkindsofitemsweareconcernedwith.Inthiscase,wejustwanttodealwiththemainsectionofthecontrol,sowechecktomakesuretheiteminquestioniseitheranItemoranAlternatingItem.Thisishandledbytheifstatement.Wegetthecurrentitemfromourinputparameter,e,andcompareittotheItemTypesweareconcernedwith.ForyouVBguys,||means"Or".
Note:IneglectedtousealternatingitemswhenIfirstwrotethisapplication,sotheusersemailwasdisplayedforeveryotheritem,buttheusersIDwasdisplayedfortheothers!
Ok,nowIvegotsomeTracinginplacetohelpmewithdebugging.ThisjustoutputsthetypeofthecurrentItem,andletsmeverifythatitisinfacteitheranItemoranAlternatingItem.Youcanleavethisoutofyourimplementation.
NextIgrabtheuser_id.Thisisoneuglypieceofcode.Letmerepeatithereandgothroughitpiecebypiece:
intuser_id=Int32.Parse(((System.Data.Common.DbDataRecord)e.Item.DataItem)["user_id"].ToString());Letsstartwiththeinnermostparentheses,inred.ThisisC#smethodofTypeCasting,andisnecessarytoconvertthecurrentDataItemtotheDbDataRecordtype.Theorangesetofparenthesescompletesthisoperation.Forallintentsandpurposes,thecontentsoftheorangeparenthesesareconsideredtobeaDbDataRecord.Movingontothegreen,thisallowsustothenreferencethe"user_id"elementofthisrecord,usingC#sarray/collectionsyntax(inVBthiswoulduse()insteadof[]),andconvertthecontentstoaString,becausethatiswhatInt32.Parseexpects.Finallymovingouttotheblack,Int32.ParseconvertsaStringintoanint.Theresultsofthisconversionarethenstoredinmyuser_idvariableoftypeint.OnthenextlineIhavesomemorediagnosticcodetooutputtheuser_idtotheTracelog.
Ok,sonowwehaveauser_id.ThenextchunkofcodeusessomecustomcontrolsthatIwrotetohandlemyUsers.ThecontrolismodelledaftertheonesfoundintheIBuySpyApplication.Inthiscase,IUserDetailsclassthatholdsmyusersnameandemailaddressbycallingthegetUserDetailsmethodofmyUserclass.Thenextlineisanotherhairyone,though:
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).Text=objUser.first_name+""+objUser.last_name+"("+objUser.email+")";
Again,startingfromthemiddlemostparens,wehaveanothertypecastingoperationbeingdone.TheredcodeisusedtoconverttheorangecodeintoaHyperLink.TheorangecodeisusedtofindthecontrolwhoseIDis"myuser"withinthecurrentitem.Inmytemplateformycolumninmydatagrid,Ihavean<asp:HyperLinkid="myuser"/>tagthatthiscoderefersto.Therestofthisblockofcodesetsthetextofthishyperlinktotheusersnameandemailaddress.ThehyperlinktaglookslikethisinmyDataGrid:<asp:hyperlinkID="myuser"Runat="server"><%#DataBinder.Eval(Container.DataItem,"user_id")%></asp:hyperlink>
Bynowthistypecastingisgettingtobeoldhat.Thenextlineprettymuchdoesthesamestuffasthepreviousline,butinthiscaseweresettingtheNavigateUrlpropertyofourHyperLinkto"mailto:"andtheusersemailaddress.Onceagainthisisfollowedbysomemorediagnostictracing.
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).NavigateUrl="mailto:"+objUser.email;
Thatsitfortheemail.Task1iscomplete.Nowwewanttotruncatethedescriptionifitistoolong.Wedothisusingsimilartechniques.First,wegrabthe"description"fromthecurrentDataItemafterconvertingittoaDbDataRecordtype.Thenweconvertittoastringandassignittoavariable,desc(allinoneline).Next,wechecktoseeifitslengthismorethan100,andifitis,weconvertittojusttheleft100characters(usingSubstring--inVBwewouldhaveusedLeft())andtackona"..."totheendtoshowtheusersthatthereismoretext.Finally,weusetheFindControlsyntaxoncemoretolocatethedescriptionLabelcontrolwithinourtemplate,andsetitsTextpropertytotheresult.
Thats2tasksdown.Onetogo.ThisisthemostcommonlyaskedforfeatureofDataGridsandDataLists:howtohideaparticularroworitemwithinadataboundlist.Inthiscase,IusemycustomSecuritycontroltodetermineiftheuseristheownerofthecurrentregularexpression.Iftheyarent,oriftheyarentloggedinandAuthenticated,thenIsetthetablecellholdingmyEdittagsVisiblepropertytofalse.Inordertodothis,IhadtomakemytablecellanHtmlControlbyaddingrunat="server"toitandgivingitanID.Inamedthetablecell"editTD",andIcanuseFindControltolocatethecellwithinmyItemandaccessitsproperties.Thecellitselfislistedhere:<tdalign="right"valign="top"id="editTD"runat="server">
[<ahref=Edit.aspx?regexp_id=<%#Server.UrlEncode(DataBinder.Eval(Container.DataItem,"regexp_id").ToString())%>
title="Clicktoedit.">Edit</a>]
</td>
Thatsallthereistooit.Formostpeople,theywanttoknowhowtohidesomethingifitsvalueisnull.JustdothesamethingImdoinghere,butreplacetheifstatementthatisreferringtosecuritywithonethatchecksthevalueofthevariable.Youwillprobablyneedtousethe(System.Data.Common.DbDataRecord)e.Item.DataItem)syntaxdescribedearliertoaccessyourdataandcheckitfornull,butthatsallthereistoit.
Summary
Manipulatingorhidingindividualelementsofadataboundlistorgridisnotverydifficultonceyouknowafewtricks.However,thecodeISprettydarnedugly.Thecodeonthispageworks,andthatisthebestthingthatcanbesaidofanyexample.YoucanseeitinactionatASPSmithRegularExpressionLibrary.Ifyouhavetroublegettingthistoworkwithyourown,Isuggestthatyoufirstcompareyoucodewithmine,andifthatdoesntyieldanyinsight,asktheASP.NETDataexpertsontheASPNGDataListserv.Besuretoincludeyourfailingcodeinyourques
[img=1border=0style=,1src=]http://www.ckuyun.com/[/img]
无论谁倒了对双方阵营的粉丝们也是有害无益。 |
|