Sei sulla pagina 1di 23

Thistutorialispartofaset.FindoutmoreaboutdataaccesswithASP.

NETintheWorkingwithData
inASP.NET2.0sectionoftheASP.NETsiteathttp://www.asp.net/learn/dataaccess/default.aspx.

WorkingwithDatainASP.NET2.0::Addingand
RespondingtoButtonstoaGridView
Introduction
Whilemanyreportingscenariosinvolvereadonlyaccesstothereportdata,itsnotuncommonforreportsto
includetheabilitytoperformactionsbaseduponthedatadisplayed.TypicallythisinvolvedaddingaButton,
LinkButton,orImageButtonWebcontrolwitheachrecorddisplayedinthereportthat,whenclicked,causesa
postbackandinvokessomeserversidecode.Editinganddeletingthedataonarecordbyrecordbasisisthemost
commonexample.Infact,aswesawstartingwiththe OverviewofInserting,Updating,andDeletingDatatutorial,
editinganddeletingissocommonthattheGridView,DetailsView,andFormViewcontrolscansupportsuch
functionalitywithouttheneedforwritingasinglelineofcode.

InadditiontoEditandDeletebuttons,theGridView,DetailsView,andFormViewcontrolscanalsoinclude
Buttons,LinkButtons,orImageButtonsthat,whenclicked,performsomecustomserversidelogic.Inthistutorial
welllookathowtoaddcustombuttons,bothtoatemplateandtothefieldsofaGridVieworDetailsViewcontrol.
Inparticular,wellbuildaninterfacethathasaFormViewthatallowstheusertopagethroughthesuppliers.Fora
givensupplier,theFormViewwillshowinformationaboutthesupplieralongwithaButtonWebcontrolthat,if
clicked,willmarkalloftheirassociatedproductsasdiscontinued.Additionally,aGridViewliststhoseproducts
providedbytheselectedsupplier,witheachrowcontaining IncreasePriceandDiscountPrice Buttonsthat,if
clicked,raiseorreducetheproductsUnitPrice by10%(seeFigure1).

1 of23
Figure1:BoththeFormViewandGridViewContainButtonsThatPerformCustomActions

Step1:AddingtheButtonTutorialWebPages
Beforewelookathowtoaddacustombuttons,letsfirsttakeamomenttocreatetheASP.NETpagesinour
websiteprojectthatwellneedforthistutorial.StartbyaddinganewfoldernamedCustomButtons.Next,addthe
followingtwoASP.NETpagestothatfolder,makingsuretoassociateeachpagewiththeSite.master master
page:

l Default.aspx
l CustomButtons.aspx

Figure2:AddtheASP.NETPagesfortheCustomButtonsRelatedTutorials

Likeintheotherfolders,Default.aspx intheCustomButtons folderwilllistthetutorialsinitssection.Recall


thattheSectionLevelTutorialListing.ascx UserControlprovidesthisfunctionality.Therefore,addthisUser
ControltoDefault.aspx bydraggingitfromtheSolutionExplorerontothepagesDesignview.

2 of23
Figure3:AddtheSectionLevelTutorialListing.ascx UserControltoDefault.aspx

Lastly,addthepagesasentriestotheWeb.sitemap file.Specifically,addthefollowingmarkupafterthePaging
andSorting<siteMapNode>:

<siteMapNode
title="AddingCustomButtons"
description="SamplesofReportsthatIncludeButtonsforPerforming
ServerSideActions"
url="~/CustomButtons/Default.aspx">

<siteMapNode
title="UsingButtonFieldsandButtonsinTemplates"
description="ExamineshowtoaddcustomButtons,LinkButtons,
orImageButtonsasButtonFieldsorwithintemplates."
url="~/CustomButtons/CustomButtons.aspx"/>

</siteMapNode>

AfterupdatingWeb.sitemap,takeamomenttoviewthetutorialswebsitethroughabrowser.Themenuontheleft
nowincludesitemsfortheediting,inserting,anddeletingtutorials.

3 of23
Figure4:TheSiteMapNowIncludestheEntryfortheCustomButtonsTutorial

Step2:AddingaFormViewthatListstheSuppliers
LetsgetstartedwiththistutorialbyaddingtheFormViewthatliststhesuppliers.AsdiscussedintheIntroduction,
thisFormViewwillallowtheuser topagethroughthesuppliers,showingtheproductsprovidedbythesupplierin
aGridView.Additionally,thisFormViewwillincludeaButtonthat,whenclicked,willmarkallofthesuppliers
productsasdiscontinued.BeforeweconcernourselveswithaddingthecustombuttontotheFormView,letsfirst
justcreatetheFormViewsothatitdisplaysthesupplierinformation.

StartbyopeningtheCustomButtons.aspx pageintheCustomButtons folder.AddaFormViewtothepageby


draggingitfromtheToolboxontotheDesignerandsetitsID propertytoSuppliers.FromtheFormViewssmart
tag,opttocreateanewObjectDataSourcenamedSuppliersDataSource.

4 of23
Figure5:CreateaNewObjectDataSourceNamedSuppliersDataSource

ConfigurethisnewObjectDataSourcesuchthatitqueriesfromtheSuppliersBLL classsGetSuppliers()
method(seeFigure6).SincethisFormViewdoesnotprovideaninterfaceforupdatingthesupplierinformation,
selectthe(None)optionfromthedropdownlistintheUPDATEtab.

5 of23
Figure6:ConfiguretheDataSourcetousetheSuppliersBLL ClasssGetSuppliers() Method

AfterconfiguringtheObjectDataSource,VisualStudiowillgenerateanInsertItemTemplate,
EditItemTemplate,andItemTemplate fortheFormView.RemovetheInsertItemTemplate and
EditItemTemplate andmodifytheItemTemplate sothatitdisplaysjustthesupplierscompanynameandphone
number.Finally,turnonpagingsupportfortheFormViewbycheckingtheEnablePagingcheckboxfromitssmart
tag(orbysettingitsAllowPaging propertytoTrue).Afterthesechangesyourpagesdeclarativemarkupshould
looksimilartothefollowing:
<asp:FormViewID="Suppliers"runat="server"DataKeyNames="SupplierID"
DataSourceID="SuppliersDataSource"EnableViewState="False"AllowPaging="True">
<ItemTemplate>
<h3>
<asp:LabelID="CompanyName"runat="server"
Text='<%#Bind("CompanyName")%>'/>
</h3>
<b>Phone:</b>
<asp:LabelID="PhoneLabel"runat="server"Text='<%#Bind("Phone")%>'/>
</ItemTemplate>
</asp:FormView>

<asp:ObjectDataSourceID="SuppliersDataSource"runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliers"TypeName="SuppliersBLL">
</asp:ObjectDataSource>

Figure7showstheCustomButtons.aspxpagewhenviewedthroughabrowser.

6 of23
Figure7:TheFormViewListstheCompanyName andPhone FieldsfromtheCurrentlySelectedSupplier

Step3:AddingaGridViewthatListstheSelected
SuppliersProducts
BeforeweaddtheDiscontinueAllProductsButtontotheFormViewstemplate,letsfirstaddaGridView
beneaththeFormViewthatliststheproductsprovidedbytheselectedsupplier.Toaccomplishthis,adda
GridViewtothepage,setitsID propertytoSuppliersProducts,andaddanewObjectDataSourcenamed
SuppliersProductsDataSource.

7 of23
Figure8:CreateaNewObjectDataSourceNamedSuppliersProductsDataSource

ConfigurethisObjectDataSourcetousetheProductsBLLclasssGetProductsBySupplierID(supplierID)
method(seeFigure9).WhilethisGridViewwillallowforaproductspricetobeadjusted,itwontbeusingthe
builtineditingordeletingfeaturesfromtheGridView.Therefore,wecansetthedropdownlistto(None)forthe
ObjectDataSourcesUPDATE,INSERT,andDELETEtabs.

8 of23
Figure9:ConfiguretheDataSourcetousetheProductsBLL ClasssGetProductsBySupplierID
(supplierID) Method

SincetheGetProductsBySupplierID(supplierID) methodacceptsaninputparameter,theObjectDataSource
wizardpromptsusforthesourceofthisparametervalue.TopassintheSupplierID valuefromtheFormView,set
theParametersourcedropdownlisttoControlandtheControlIDdropdownlisttoSuppliers (theIDofthe
FormViewcreatedinStep2).

9 of23
Figure10:IndicatethatthesupplierID ParameterShouldComefromtheSuppliers FormViewControl

AftercompletingtheObjectDataSourcewizard,theGridViewwillcontainaBoundFieldorCheckBoxFieldfor
eachoftheproductsdatafields.LetstrimthisdowntoshowjusttheProductName andUnitPrice BoundFields
alongwiththeDiscontinued CheckBoxFieldfurthermore,letsformattheUnitPrice BoundFieldsuchthatits
textisformattedasacurrency.YourGridViewandSuppliersProductsDataSource ObjectDataSources
declarativemarkupshouldlooksimilartothefollowingmarkup:

<asp:GridViewID="SuppliersProducts"AutoGenerateColumns="False"
DataKeyNames="ProductID"DataSourceID="SuppliersProductsDataSource"
EnableViewState="False"runat="server">
<Columns>
<asp:BoundFieldDataField="ProductName"HeaderText="Product"
SortExpression="ProductName"/>
<asp:BoundFieldDataField="UnitPrice"HeaderText="Price"
SortExpression="UnitPrice"DataFormatString="{0:C}"
HtmlEncode="False"/>
<asp:CheckBoxFieldDataField="Discontinued"HeaderText="Discontinued"
SortExpression="Discontinued"/>
</Columns>
</asp:GridView>

<asp:ObjectDataSourceID="SuppliersProductsDataSource"runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsBySupplierID"TypeName="ProductsBLL">
<SelectParameters>
<asp:ControlParameterControlID="Suppliers"Name="supplierID"
PropertyName="SelectedValue"Type="Int32"/>
</SelectParameters>
</asp:ObjectDataSource>

Atthispointourtutorialdisplaysamaster/detailsreport,allowingtheusertopickasupplierfromtheFormViewat
thetopandtoviewtheproductsprovidedbythatsupplierthroughtheGridViewatthebottom.Figure11showsa

10 of23
screenshotofthispagewhenselectingtheTokyoTraderssupplierfromtheFormView.

Figure11:TheSelectedSuppliersProductsareDisplayedintheGridView

Step4:CreatingDALandBLLMethodsto
DiscontinueAllProductsforaSupplier
BeforewecanaddaButtontotheFormViewthat,whenclicked,discontinuesallofthesuppliersproducts,we
firstneedtoaddamethodtoboththeDALandBLLthatperformsthisaction.Inparticular,thismethodwillbe
namedDiscontinueAllProductsForSupplier(supplierID).WhentheFormViewsButtonisclicked,well
invokethismethodintheBusinessLogicLayer,passingintheselectedsuppliersSupplierIDtheBLLwillthen
calldowntothecorrespondingDataAccessLayermethod,whichwillissueanUPDATE statementtothedatabase
thatdiscontinuesthespecifiedsuppliersproducts.

Aswehavedoneinourprevioustutorials,welluseabottomupapproach,startingwithcreatingtheDALmethod,
thentheBLLmethod,andfinallyimplementingthefunctionalityintheASP.NETpage.OpentheNorthwind.xsd
TypedDataSetintheApp_Code/DAL folderandaddanewmethodtotheProductsTableAdapter (rightclickon
theProductsTableAdapter andchooseAddQuery).DoingsowillbringuptheTableAdapterQuery
Configurationwizard,whichwalksusthroughtheprocessofaddingthenewmethod.Startbyindicatingthatour
DALmethodwilluseanadhocSQLstatement.

11 of23
Figure12:CreatetheDALMethodUsinganAdHocSQLStatement

Next,thewizardpromptsusastowhattypeofquerytocreate.SincetheDiscontinueAllProductsForSupplier
(supplierID) methodwillneedtoupdatetheProducts databasetable,settingtheDiscontinued fieldto1forall
productsprovidedbythespecifiedsupplierID,weneedtocreateaquerythatupdatesdata.

12 of23
Figure13:ChoosetheUPDATEQueryType

ThenextwizardscreenprovidestheTableAdaptersexistingUPDATE statement,whichupdateseachofthefields
definedintheProducts DataTable.Replacethisquerytextwiththefollowingstatement:

UPDATE[Products]SET
Discontinued=1
WHERESupplierID=@SupplierID

AfterenteringthisqueryandclickingNext,thelastwizardscreenasksforthenewmethodsname use
DiscontinueAllProductsForSupplier.CompletethewizardbyclickingtheFinishbutton.Uponreturningtothe
DataSetDesigneryoushouldseeanewmethodintheProductsTableAdapter named
DiscontinueAllProductsForSupplier(@SupplierID).

13 of23
Figure14:NametheNewDALMethodDiscontinueAllProductsForSupplier

WiththeDiscontinueAllProductsForSupplier(supplierID) methodcreatedintheDataAccessLayer,our
nexttaskistocreatetheDiscontinueAllProductsForSupplier(supplierID) methodintheBusinessLogic
Layer.Toaccomplishthis,opentheProductsBLL classfileandaddthefollowing:

PublicFunctionDiscontinueAllProductsForSupplier(supplierIDAsInteger)AsInteger
ReturnAdapter.DiscontinueAllProductsForSupplier(supplierID)
EndFunction

ThismethodsimplycallsdowntotheDiscontinueAllProductsForSupplier(supplierID) methodintheDAL,
passingalongtheprovidedsupplierID parametervalue.Iftherewereanybusinessrulesthatonlyalloweda
suppliersproductstobediscontinuedundercertaincircumstances,thoserulesshouldbeimplementedhere,inthe
BLL.

Note: UnliketheUpdateProduct overloadsintheProductsBLL class,the


DiscontinueAllProductsForSupplier(supplierID) methodsignaturedoesnotincludethe
DataObjectMethodAttribute attribute(<System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Update,Boolean)>).Thisprecludesthe
DiscontinueAllProductsForSupplier(supplierID) methodfromtheObjectDataSourcesConfigureData
SourcewizardsdropdownlistintheUPDATEtab.Iveomittedthisattributebecausewellbecallingthe
DiscontinueAllProductsForSupplier(supplierID) methoddirectlyfromaneventhandlerinourASP.NET
page.

Step5:AddingaDiscontinueAllProductsButton
totheFormView

14 of23
WiththeDiscontinueAllProductsForSupplier(supplierID) methodintheBLLandDALcomplete,thefinal
stepforaddingtheabilitytodiscontinueallproductsfortheselectedsupplieristoaddaButtonWebcontroltothe
FormViewsItemTemplate.LetsaddsuchaButtonbelowthesuppliersphonenumberwiththebuttontext,
DiscontinueAllProductsandanID propertyvalueofDiscontinueAllProductsForSupplier.Youcanaddthis
ButtonWebcontrolthroughtheDesignerbyclickingontheEditTemplateslinkintheFormViewssmarttag(see
Figure15),ordirectlythroughthedeclarativesyntax.

Figure15:AddaDiscontinueAllProductsButtonWebControltotheFormViewsItemTemplate

WhentheButtonisclickedbyauservisitingthepage,apostbackensuesandtheFormViewsItemCommand event
fires.ToexecutecustomcodeinresponsetothisButtonbeingclicked,wecancreateaneventhandlerforthis
event.Understand,though,thattheItemCommand eventfireswhenever any Button,LinkButton,orImageButton
WebcontrolisclickedwithintheFormView.Thatmeansthatwhentheusermovesfromonepagetoanotherinthe
FormView,theItemCommand eventfiressamethingwhentheuserclicksNew,Edit,orDeleteinaFormViewthat
supportsinserting,updating,ordeleting.

SincetheItemCommand firesregardlessofwhatbuttonisclicked,intheeventhandlerweneedawaytodetermine
iftheDiscontinueAllProductsButtonwasclickedorifitwassomeotherbutton.Toaccomplishthis,wecanset
theButtonWebcontrolsCommandName propertytosomeidentifyingvalue.WhentheButtonisclicked,this
CommandName valueispassedintotheItemCommand eventhandler,enablingustodeterminewhetherthe
DiscontinueAllProductsButtonwasthebuttonclicked.SettheDiscontinueAllProductsButtons
CommandName propertytoDiscontinueProducts.

Finally,letsuseaclientsideconfirmdialogboxtoensurethattheuserreallywantstodiscontinuetheselected
suppliersproducts.AswesawintheAddingClientSideConfirmationWhenDeletingtutorial,thiscanbe
accomplishedwithabitofJavaScript.Inparticular,settheButtonWebcontrolsOnClientClickpropertyto
returnconfirm('Thiswillmark_all_ofthissupplier\'sproductsasdiscontinued.Areyou
certainyouwanttodothis?')

15 of23
Aftermakingthesechanges,theFormViewsdeclarativesyntaxshouldlooklikethefollowing:
<asp:FormViewID="Suppliers"runat="server"DataKeyNames="SupplierID"
DataSourceID="SuppliersDataSource"EnableViewState="False"
AllowPaging="True">
<ItemTemplate>
<h3><asp:LabelID="CompanyName"runat="server"
Text='<%#Bind("CompanyName")%>'></asp:Label></h3>
<b>Phone:</b>
<asp:LabelID="PhoneLabel"runat="server"Text='<%#Bind("Phone")%>'/>
<br/>
<asp:ButtonID="DiscontinueAllProductsForSupplier"runat="server"
CommandName="DiscontinueProducts"Text="DiscontinueAllProducts"
OnClientClick="returnconfirm('Thiswillmark_all_ofthissupplier\'s
productsasdiscontinued.Areyoucertainyouwanttodothis?')"/>
</ItemTemplate>
</asp:FormView>

Next,createaneventhandlerfortheFormViewsItemCommand event.Inthiseventhandlerweneedtofirst
determinewhethertheDiscontinueAllProductsButtonwasclicked.Ifso,wewanttocreateaninstanceofthe
ProductsBLL classandinvokeitsDiscontinueAllProductsForSupplier(supplierID) method,passinginthe
SupplierID oftheselectedFormView:

ProtectedSubSuppliers_ItemCommand(senderAsObject,eAsFormViewCommandEventArgs)_
HandlesSuppliers.ItemCommand
Ife.CommandName.CompareTo("DiscontinueProducts")=0Then
'The"DiscontinueAllProducts"Buttonwasclicked.
'InvoketheProductsBLL.DiscontinueAllProductsForSupplier(supplierID)method

'First,gettheSupplierIDselectedintheFormView
DimsupplierIDAsInteger=CType(Suppliers.SelectedValue,Integer)

'Next,createaninstanceoftheProductsBLLclass
DimproductInfoAsNewProductsBLL()

'Finally,invoketheDiscontinueAllProductsForSupplier(supplierID)method
productInfo.DiscontinueAllProductsForSupplier(supplierID)
EndIf
EndSub

NotethattheSupplierID ofthecurrentselectedsupplierintheFormViewcanbeaccessedusingtheFormViews
SelectedValue property.TheSelectedValue propertyreturnsthefirstdatakeyvaluefortherecordbeing
displayedintheFormView.TheFormViewsDataKeyNames property,whichindicatesthedatafieldsfromwhich
thedatakeyvaluesarepulledfrom,wasautomaticallysettoSupplierID byVisualStudiowhenbindingthe
ObjectDataSourcetotheFormViewbackinStep2.

WiththeItemCommand eventhandlercreated,takeamomenttotestoutthepage.BrowsetotheCooperativade
Quesos'LasCabras'supplier(itsthefifthsupplierintheFormViewforme).Thissupplierprovidestwoproducts,
QuesoCabralesandQuesoManchegoLaPastora,bothofwhichare not discontinued.

ImaginethatCooperativadeQuesos'LasCabras'hasgoneoutofbusinessandthereforeitsproductsaretobe
discontinued.ClicktheDiscontinueAllProducts Button.Thiswilldisplaytheclientsideconfirmdialogbox
(seeFigure16).

16 of23
Figure16:CooperativadeQuesos'LasCabras'SuppliesTwoActiveProducts

IfyouclickOKintheclientsideconfirmdialogbox,theformsubmissionwillproceed,causingapostbackin
whichtheFormViewsItemCommand eventwillfire.Theeventhandlerwecreatedwillthenexecute,invokingthe
DiscontinueAllProductsForSupplier(supplierID) methodanddiscontinuingboththeQuesoCabralesand
QuesoManchegoLaPastoraproducts.

IfyouhavedisabledtheGridViewsviewstate,theGridViewisbeingreboundtotheunderlyingdatastoreon
everypostback,andthereforewillimmediatelybeupdatedtoreflectthatthesetwoproductsarenowdiscontinued
(seeFigure17).If,however,youhavenotdisabledviewstateintheGridView,youwillneedtomanuallyrebind
thedatatotheGridViewaftermakingthischange.Toaccomplishthis,simplymakeacalltotheGridViews
DataBind() methodimmediatelyafterinvokingtheDiscontinueAllProductsForSupplier(supplierID)
method.

17 of23
Figure17:AfterClickingtheDiscontinueAllProductsButton,theSuppliersProductsareUpdated
Accordingly

Step6:CreatinganUpdateProductOverloadinthe
BusinessLogicLayerforAdjustingaProductsPrice
LikewiththeDiscontinueAllProducts ButtonintheFormView,inordertoaddbuttonsforincreasingand
decreasingthepriceforaproductintheGridViewweneedtofirstaddtheappropriateDataAccessLayerand
BusinessLogicLayermethods.SincewealreadyhaveamethodthatupdatesasingleproductrowintheDAL,we
canprovidesuchfunctionalitybycreatinganewoverloadfortheUpdateProduct methodintheBLL.

OurpastUpdateProduct overloadshavetakeninsomecombinationofproductfieldsasscalarinputvaluesand
havethenupdatedjustthosefieldsforthespecifiedproduct.Forthisoverloadwellvaryslightlyfromthisstandard
andinsteadpassintheproductsProductID andthepercentagebywhichtoadjusttheUnitPrice (asopposedto
passinginthenew,adjustedUnitPrice itself).Thisapproachwillsimplifythecodeweneedtowriteinthe
ASP.NETpagecodebehindclass,sincewedonthavetobotherwithdeterminingthecurrentproducts
UnitPrice.

TheUpdateProduct overloadforthistutorialisshownbelow:

PublicFunctionUpdateProduct_
(unitPriceAdjustmentPercentageAsDecimal,productIDAsInteger)AsBoolean
DimproductsAsNorthwind.ProductsDataTable=Adapter.GetProductByProductID(productID)

Ifproducts.Count=0Then
'nomatchingrecordfound,returnfalse
ReturnFalse
EndIf

DimproductAsNorthwind.ProductsRow=products(0)

'AdjusttheUnitPricebythespecifiedpercentage(ifit'snotNULL)
IfNotproduct.IsUnitPriceNull()Then
product.UnitPrice*=unitPriceAdjustmentPercentage
EndIf

18 of23
'Updatetheproductrecord
DimrowsAffectedAsInteger=Adapter.Update(product)

'Returntrueifpreciselyonerowwasupdated,otherwisefalse
ReturnrowsAffected=1
EndFunction

ThisoverloadretrievesinformationaboutthespecifiedproductthroughtheDALsGetProductByProductID
(productID) method.ItthencheckstoseewhethertheproductsUnitPrice isassignedadatabaseNULL value.If
itis,thepriceisleftunaltered.If,however,thereisanonNULLUnitPrice value,themethodupdatestheproducts
UnitPrice bythespecifiedpercent(unitPriceAdjustmentPercent).

Step7:AddingtheIncreaseandDecreaseButtonsto
theGridView
TheGridView(andDetailsView)arebothmadeupofacollectionoffields.InadditiontoBoundFields,
CheckBoxFields,andTemplateFields,ASP.NETincludestheButtonField,which,asitsnameimplies,rendersasa
columnwithaButton,LinkButton,orImageButtonforeachrow.SimilartotheFormView,clickingany button
withintheGridViewpagingbuttons,EditorDeletebuttons,sortingbuttons,andsoon causesapostbackand
raisestheGridViewsRowCommand event.

TheButtonFieldhasaCommandName propertythatassignsthespecifiedvaluetoeachofitsButtonsCommandName
properties.LikewiththeFormView,theCommandName valueisusedbythe RowCommand eventhandlertodetermine
whichbuttonwasclicked.

LetsaddtwonewButtonFieldstotheGridView,onewithabuttontextPrice+10%andtheotherwiththetext
Price10%. ToaddtheseButtonFields,clickontheEditColumnslinkfromtheGridViewssmarttag,selectthe
ButtonFieldfieldtypefromthelistintheupperleftandclicktheAddbutton.

19 of23
Figure18:AddTwoButtonFieldstotheGridView

MovethetwoButtonFieldssothattheyappearasthefirsttwoGridViewfields.Next,settheText propertiesof
thesetwoButtonFieldstoPrice+10%andPrice10%andtheCommandName propertiestoIncreasePriceand
DecreasePrice, respectively.Bydefault,aButtonFieldrendersitscolumnofbuttonsasLinkButtons.Thiscanbe
changed,however,throughtheButtonFieldsButtonType property.LetshavethesetwoButtonFieldsrenderedas
regularpushbuttonstherefore,settheButtonType propertytoButton.Figure19showstheFieldsdialogbox
afterthesechangeshavebeenmadefollowingthatistheGridViewsdeclarativemarkup.

Figure19:ConfiguretheButtonFieldsText,CommandName,andButtonType Properties

<asp:GridViewID="SuppliersProducts"runat="server"AutoGenerateColumns="False"
DataKeyNames="ProductID"DataSourceID="SuppliersProductsDataSource"
EnableViewState="False">
<Columns>
<asp:ButtonFieldButtonType="Button"CommandName="IncreasePrice"
Text="Price+10%"/>
<asp:ButtonFieldButtonType="Button"CommandName="DecreasePrice"
Text="Price10%"/>
<asp:BoundFieldDataField="ProductName"HeaderText="Product"
SortExpression="ProductName"/>
<asp:BoundFieldDataField="UnitPrice"HeaderText="Price"
SortExpression="UnitPrice"DataFormatString="{0:C}"
HtmlEncode="False"/>
<asp:CheckBoxFieldDataField="Discontinued"HeaderText="Discontinued"
SortExpression="Discontinued"/>
</Columns>
</asp:GridView>

WiththeseButtonFieldscreated,thefinalstepistocreateaneventhandlerfortheGridViewsRowCommand event.
Thiseventhandler,iffiredbecauseeitherthePrice+10%or Price10%buttonswereclicked,needsto
determinetheProductID fortherowwhosebuttonwasclickedandtheninvoketheProductsBLL classs

20 of23
UpdateProduct method,passingintheappropriateUnitPrice percentageadjustmentalongwiththeProductID .
Thefollowingcodeperformsthesetasks:
ProtectedSubSuppliersProducts_RowCommand_
(senderAsObject,eAsGridViewCommandEventArgs)_
HandlesSuppliersProducts.RowCommand
Ife.CommandName.CompareTo("IncreasePrice")=0OrElse_
e.CommandName.CompareTo("DecreasePrice")=0Then
'TheIncreasePriceorDecreasePriceButtonhasbeenclicked

'DeterminetheIDoftheproductwhosepricewasadjusted
DimproductIDAsInteger=Convert.ToInt32(_
SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value)

'Determinehowmuchtoadjusttheprice
DimpercentageAdjustAsDecimal
Ife.CommandName.CompareTo("IncreasePrice")=0Then
percentageAdjust=1.1
Else
percentageAdjust=0.9
EndIf

'Adjusttheprice
DimproductInfoAsNewProductsBLL()
productInfo.UpdateProduct(percentageAdjust,productID)
EndIf
EndSub

InordertodeterminetheProductID fortherowwhosePrice+10%or Price10%buttonwasclicked,weneed


toconsulttheGridViewsDataKeys collection.Thiscollectionholdsthevaluesofthefieldsspecifiedinthe
DataKeyNames propertyforeachGridViewrow.SincetheGridViewsDataKeyNames propertywassetto
ProductIDbyVisualStudiowhenbindingtheObjectDataSourcetotheGridView,DataKeys(rowIndex).Value
providestheProductID forthespecifiedrowIndex.

TheButtonFieldautomaticallypassesinthe rowIndexoftherowwhosebuttonwasclickedthroughthe
e.CommandArgument parameter.Therefore,todeterminetheProductID fortherowwhosePrice+10% orPrice
10%buttonwasclicked,weuse:Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32
(e.CommandArgument)).Value).

AswiththeDiscontinueAllProducts button,ifyouhavedisabledtheGridViewsviewstate,theGridViewis
beingreboundtotheunderlyingdatastoreoneverypostback,andthereforewillimmediatelybeupdatedtoreflect
apricechangethatoccursfromclickingeitherofthebuttons.If,however,youhavenotdisabledviewstateinthe
GridView,youwillneedtomanuallyrebindthedatatotheGridViewaftermakingthischange.Toaccomplish
this,simplymakeacalltotheGridViewsDataBind() methodimmediatelyafterinvokingtheUpdateProduct
method.

Figure20showsthepagewhenviewingtheproductsprovidedbyGrandmaKelly'sHomestead.Figure21shows
theresultsafterthePrice+10%buttonhasbeenclickedtwiceforGrandma'sBoysenberrySpreadandthe
Price10%buttononceforNorthwoodsCranberrySauce.

21 of23
Figure20:TheGridViewIncludesPrice+10% andPrice10% Buttons

Figure21:ThePricesfortheFirstandThirdProductHaveBeenUpdatedviathePrice+10%and
Price10% Buttons

Note: TheGridView(andDetailsView)canalsohaveButtons,LinkButtons,orImageButtonsaddedtotheir
TemplateFields.AswiththeBoundField,theseButtons,whenclicked,willinduceapostback,raisingthe
GridViewsRowCommand event.WhenaddingbuttonsinaTemplateField,however,theButtons
CommandArgument isnotautomaticallysettotheindexoftherowasitiswhenusingButtonFields.Ifyouneedto
determinetherowindexofthebuttonthatwasclickedwithintheRowCommand eventhandler,youllneedto
manuallysettheButtonsCommandArgument propertyinitsdeclarativesyntaxwithintheTemplateField,using
codelike:
<asp:Buttonrunat="server"...CommandArgument='<%#CType(Container,GridViewRow).RowIndex%
>'/>.

Summary
TheGridView,DetailsView,andFormViewcontrolsallcanincludeButtons,LinkButtons,orImageButtons.Such
buttons,whenclicked,causeapostbackandraisetheItemCommand eventintheFormViewandDetailsView

22 of23
controlsandtheRowCommand eventintheGridView.ThesedataWebcontrolshavebuiltinfunctionalitytohandle
commoncommandrelatedactions,suchasdeletingoreditingrecords.However,wecanalsousebuttonsthat,
whenclicked,respondwithexecutingourowncustomcode.

Toaccomplishthis,weneedtocreateaneventhandlerfortheItemCommand orRowCommand event.Inthisevent


handlerwefirstchecktheincomingCommandName valuetodeterminewhichbuttonwasclickedandthentake
appropriatecustomaction.InthistutorialwesawhowtousebuttonsandButtonFieldstodiscontinueallproducts
foraspecifiedsupplierortoincreaseordecreasethepriceofaparticularproductby10%.

HappyProgramming!

AbouttheAuthor
ScottMitchell,authorofsixASP/ASP.NETbooksandfounderof 4GuysFromRolla.com,hasbeenworkingwith
MicrosoftWebtechnologiessince1998.Scottworksasanindependentconsultant,trainer,andwriter,recently
completinghislatestbook, SamsTeachYourselfASP.NET2.0in24Hours.Hecanbereachedat
mitchell@4guysfromrolla.comorviahisblog,whichcanbefoundatScottOnWriting.NET.

23 of23

Potrebbero piacerti anche