You are on page 1of 27

Thistutorialispartofaset.FindoutmoreaboutdataaccesswithASP.

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

WorkingwithDatainASP.NET2.0::Addinga
GridViewColumnofRadioButtons
Introduction
TheGridViewcontroloffersagreatdealofbuiltinfunctionality.Itincludesanumberofdifferentfieldsfor
displayingtext,images,hyperlinks,andbuttons.Itsupportstemplatesforfurthercustomization.Withafewclicks
ofthemouse,itspossibletomakeaGridViewwhereeachrowcanbeselectedviaabutton,ortoenableeditingor
deletingcapabilities.Despitetheplethoraofprovidedfeatures,therewilloftenbesituationsinwhichadditional,
nonsupportedfeatureswillneedtobeadded.Inthistutorialandthenexttwowellexaminehowtoenhancethe
GridViewsfunctionalitytoincludeadditionalfeatures.
Thistutorialandthenextonefocusonenhancingtherowselectionprocess.AsexaminedintheMaster/Detail
UsingaSelectableMasterGridViewwithaDetailsDetailView,wecanaddaCommandFieldtotheGridViewthat
includesaSelectbutton.Whenclicked,apostbackensuesandtheGridViewsSelectedIndex propertyisupdated
totheindexoftherowwhoseSelectbuttonwasclicked.IntheMaster/DetailUsingaSelectableMasterGridView
withaDetailsDetailView tutorial,wesawhowtousethisfeaturetodisplaydetailsfortheselectedGridViewrow.
WhiletheSelectbuttonworksinmanysituations,itmaynotworkaswellforothers.Ratherthanusingabutton,
twootheruserinterfaceelementsarecommonlyusedforselection:theradiobuttonandcheckbox.Wecan
augmenttheGridViewsothatinsteadofaSelectbutton,eachrowcontainsaradiobuttonorcheckbox.In
scenarioswheretheusercanonlyselectoneoftheGridViewrecords,theradiobuttonmightbepreferredoverthe
Selectbutton.Insituationswheretheusercanpotentiallyselectmultiplerecordssuchasinawebbasedemail
application,whereausermightwanttoselectmultiplemessagestodelete thecheckboxoffersfunctionalitythat
isnotavailablefromtheSelectbuttonorradiobuttonuserinterfaces.
ThistutoriallooksathowtoaddacolumnofradiobuttonstotheGridView.Theproceedingtutorialexploresusing
checkboxes.

Step1:CreatingtheEnhancingtheGridViewWebPages
BeforewestartenhancingtheGridViewtoincludeacolumnofradiobuttons,letsfirsttakeamomenttocreatethe
ASP.NETpagesinourwebsiteprojectthatwellneedforthistutorialandthenexttwo.Startbyaddinganew
foldernamedEnhancedGridView.Next,addthefollowingASP.NETpagestothatfolder,makingsuretoassociate
eachpagewiththeSite.master masterpage:
Default.aspx
RadioButtonField.aspx
l CheckBoxField.aspx
l InsertThroughFooter.aspx
l
l

1 of27

Figure1:AddtheASP.NETPagesfortheSqlDataSourceRelatedTutorials

Likeintheotherfolders,Default.aspx intheEnhancedGridView folderwilllistthetutorialsinitssection.Recall


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

2 of27

Figure2:AddtheSectionLevelTutorialListing.ascx UserControlto Default.aspx

Lastly,addthesefourpagesasentriestotheWeb.sitemap file.Specifically,addthefollowingmarkupafterthe
UsingtheSqlDataSourceControl<siteMapNode>:
<siteMapNode
title="EnhancingtheGridView"
url="~/EnhancedGridView/Default.aspx"
description="AugmenttheuserexperienceoftheGridViewcontrol.">
<siteMapNode
url="~/EnhancedGridView/RadioButtonField.aspx"
title="SelectionviaaRadioButtonColumn"
description="ExplorehowtoaddacolumnofradiobuttonsintheGridView."/>
<siteMapNode
url="~/EnhancedGridView/CheckBoxField.aspx"
title="SelectionviaaCheckboxColumn"
description="SelectmultiplerecordsintheGridViewbyusingacolumnof
checkboxes."/>
<siteMapNode
url="~/EnhancedGridView/InsertThroughFooter.aspx"
title="AddNewRecordsthroughtheFooter"
description="Learnhowtoallowuserstoaddnewrecordsthroughthe
GridView'sfooter."/>
</siteMapNode>

3 of27

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

Figure3:TheSiteMapNowIncludesEntriesfortheEnhancingtheGridViewTutorials

Step2:DisplayingtheSuppliersinaGridView
ForthistutorialletsbuildaGridViewthatliststhesuppliersfromtheUSA,witheachGridViewrowprovidinga
radiobutton.Afterselectingasupplierviatheradiobutton,theusercanviewthesuppliersproductsbyclickinga
button.Whilethistaskmaysoundtrivial,thereareanumberofsubtletiesthatmakeitparticularlytricky.Before
wedelveintothesesubtleties,letsfirstgetaGridViewlistingthesuppliers.
StartbyopeningtheRadioButtonField.aspx pageintheEnhancedGridView folderbydraggingaGridView
fromtheToolboxontotheDesigner.SettheGridViewsID toSuppliers and,fromitssmarttag,choosetocreate
anewdatasource.Specifically,createanObjectDataSourcenamedSuppliersDataSource thatpullsitsdatafrom
theSuppliersBLL object.

4 of27

Figure4:CreateaNewObjectDataSourceNamed SuppliersDataSource

5 of27

Figure5:ConfiguretheObjectDataSourcetoUsetheSuppliersBLL Class

SinceweonlywanttolistthosesuppliersintheUSA,choosetheGetSuppliersByCountry(country) method
fromthedropdownlistintheSELECTtab.

6 of27

Figure6:ConfiguretheObjectDataSourcetoUsetheSuppliersBLL Class

FromtheUPDATEtab,selectthe(None) optionandclickNext.

7 of27

Figure7:ConfiguretheObjectDataSourcetoUsetheSuppliersBLL Class

SincetheGetSuppliersByCountry(country) methodacceptsaparameter,theConfigureDataSourcewizard
promptsusforthesourceofthatparameter.Tospecifyahardcodedvalue(USA, inthisexample),leavethe
ParametersourcedropdownlistsettoNoneandenterthedefaultvalueinthetextbox.ClickFinishtocompletethe
wizard.

8 of27

Figure8:UseUSA astheDefaultValueforthecountry Parameter

Aftercompletingthewizard,theGridViewwillincludeaBoundFieldforeachofthesupplierdatafields.Remove
allbuttheCompanyName,City,andCountry BoundFields,andrenametheCompanyName BoundFields HeaderText
propertytoSupplier. Afterdoingso,theGridViewandObjectDataSourcedeclarativesyntaxshouldlooksimilar
tothefollowing.
<asp:GridViewID="Suppliers"runat="server"AutoGenerateColumns="False"
DataKeyNames="SupplierID"DataSourceID="SuppliersDataSource"
EnableViewState="False">
<Columns>
<asp:BoundFieldDataField="CompanyName"HeaderText="Supplier"
SortExpression="CompanyName"/>
<asp:BoundFieldDataField="City"HeaderText="City"
SortExpression="City"/>
<asp:BoundFieldDataField="Country"HeaderText="Country"
SortExpression="Country"/>
</Columns>
</asp:GridView>
<asp:ObjectDataSourceID="SuppliersDataSource"runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliersByCountry"TypeName="SuppliersBLL">
<SelectParameters>
<asp:ParameterDefaultValue="USA"Name="country"Type="String"/>
</SelectParameters>
</asp:ObjectDataSource>

9 of27

Forthistutorial,letsallowtheusertoviewtheselectedsuppliersproductsonthesamepageasthesupplierlist,
oronadifferentpage.Toaccommodatethis,addtwoButtonWebcontrolstothepage.IvesettheIDsofthese
twoButtonstoListProducts andSendToProducts,withtheideathatwhenListProducts isclickedapostback
willoccurandtheselectedsuppliersproductswillbelistedonthesamepage,butwhenSendToProducts is
clicked,theuserwillbewhiskedtoaanotherpagethatliststheproducts.
Figure9showstheSuppliers GridViewandthetwoButtonWebcontrolswhenviewedthroughabrowser.

Figure9:ThoseSuppliersfromtheUSAHaveTheirName,City,andCountryInformationListed

Step3:AddingaColumnofRadioButtons
AtthispointtheSuppliers GridViewhasthreeBoundFieldsdisplayingthecompanyname,city,andcountryof
eachsupplierintheUSA.Itisstilllackingacolumnofradiobuttons,however.Unfortunately,theGridView
doesntincludeabuiltinRadioButtonField,otherwisewecouldjustaddthattothegridandbedone.Instead,we
canaddaTemplateFieldandconfigureitsItemTemplate torenderaradiobutton,resultinginaradiobuttonfor
eachGridViewrow.
Initially,wemightassumethatthedesireduserinterfacecanbeimplementedbyaddingaRadioButtonWeb
controltotheItemTemplate ofaTemplateField.Whilethiswillindeedaddasingleradiobuttontoeachrowof
theGridView,theradiobuttonscannotbegroupedandthereforearenotmutuallyexclusive.Thatis,anenduseris
abletoselectmultipleradiobuttonssimultaneouslyfromtheGridView.

10 of27

EventhoughusingaTemplateFieldofRadioButtonWebcontrolsdoesnotofferthefunctionalityweneed,lets
implementthisapproach,asitsworthwhiletoexaminewhytheresultingradiobuttonsarenotgrouped.Startby
addingaTemplateFieldtotheSuppliersGridView,makingittheleftmostfield.Next,fromtheGridViewssmart
tag,clicktheEditTemplateslinkanddragaRadioButtonWebcontrolfromtheToolboxintotheTemplateFields
ItemTemplate (seeFigure10).SettheRadioButtonsID propertytoRowSelector andtheGroupName propertyto
SuppliersGroup.

Figure10:AddaRadioButtonWebControltotheItemTemplate

AftermakingtheseadditionsthroughtheDesigner,yourGridViewsmarkupshouldlooksimilartothefollowing:
<asp:GridViewID="Suppliers"runat="server"AutoGenerateColumns="False"
DataKeyNames="SupplierID"DataSourceID="SuppliersDataSource"
EnableViewState="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButtonID="RowSelector"runat="server"
GroupName="SuppliersGroup"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundFieldDataField="CompanyName"HeaderText="Supplier"
SortExpression="CompanyName"/>
<asp:BoundFieldDataField="City"HeaderText="City"
SortExpression="City"/>
<asp:BoundFieldDataField="Country"HeaderText="Country"

11 of27

SortExpression="Country"/>
</Columns>
</asp:GridView>

TheRadioButtonsGroupName propertyiswhatisusedtogroupaseriesofradiobuttons.AllRadioButtoncontrols
withthesameGroupName valueareconsideredgroupedonlyoneradiobuttoncanbeselectedfromagroupata
time.TheGroupName propertyspecifiesthevaluefortherenderedradiobuttonsname attribute.Thebrowser
examinestheradiobuttonsname attributestodeterminetheradiobuttongroupings.
WiththeRadioButtonWebcontroladdedtotheItemTemplate,visitthispagethroughabrowserandclickonthe
radiobuttonsinthegridsrows.Noticehowtheradiobuttonsarenotgrouped,makingitpossibletoselectallof
therows,asFigure11shows.

Figure11:TheGridViewsRadioButtonsareNotGrouped

Thereasontheradiobuttonsarenotgroupedisbecausetheirrenderedname attributesaredifferent,despitehaving
thesameGroupName propertysetting.Toseethesedifferences,doaView/Sourcefromthebrowserandexamine
theradiobuttonmarkup:
<inputid="ctl00_MainContent_Suppliers_ctl02_RowSelector"
name="ctl00$MainContent$Suppliers$ctl02$SuppliersGroup"
type="radio"value="RowSelector"/>
<inputid="ctl00_MainContent_Suppliers_ctl03_RowSelector"
name="ctl00$MainContent$Suppliers$ctl03$SuppliersGroup"
type="radio"value="RowSelector"/>
<inputid="ctl00_MainContent_Suppliers_ctl04_RowSelector"
name="ctl00$MainContent$Suppliers$ctl04$SuppliersGroup"

12 of27

type="radio"value="RowSelector"/>
<inputid="ctl00_MainContent_Suppliers_ctl05_RowSelector"
name="ctl00$MainContent$Suppliers$ctl05$SuppliersGroup"
type="radio"value="RowSelector"/>

Noticehowboththename andid attributesarenottheexactvaluesasspecifiedinthePropertieswindow,butare


prependedwithanumberofotherID values.TheadditionalID valuesaddedtothefrontoftherenderedid and
name attributesaretheIDsoftheradiobuttons parentcontrols the GridViewRowsIDs,theGridViewsID,the
ContentcontrolsID,andtheWebFormsID.TheseIDsareaddedsothateachrenderedWebcontrolinthe
GridViewhasauniqueid andname values.
Eachrenderedcontrolneedsadifferentname andid becausethisishowthebrowseruniquelyidentifieseach
controlontheclientsideandhowitidentifiestothewebserverwhatactionorchangehasoccurredonpostback.
Forexample,imaginethatwewantedtorunsomeserversidecodewheneveraRadioButtonscheckedstatewas
changed.WecouldaccomplishthisbysettingtheRadioButtonsAutoPostBack propertytotrue andcreatingan
eventhandlerfortheCheckChanged event.However,iftherenderedname andid valuesforalloftheradiobuttons
werethesame,onpostbackwecouldnotdeterminewhatspecificRadioButtonwasclicked.
TheshortofitisthatwecannotcreateacolumnofradiobuttonsinaGridViewusingtheRadioButtonWeb
control.Instead,wemustuseratherarchaictechniquestoensurethattheappropriatemarkupisinjectedintoeach
GridViewrow.
Note:LiketheRadioButtonWebcontrol,theradiobuttonHTMLcontrol,whenaddedtoatemplate,will
includetheuniquename attribute,makingtheradiobuttonsinthegridungrouped.Ifyouarenotfamiliar
withHTMLcontrols,feelfreetodisregardthisnote,asHTMLcontrolsarerarelyused,especiallyin
ASP.NET2.0.Butifyouareinterestedinlearningmore,seeK.ScottAllensblogentry WebControlsand
HTMLControls.

UsingaLiteralControltoInjectRadioButtonMarkup
InordertocorrectlygroupalloftheradiobuttonswithintheGridView,weneedtomanuallyinjecttheradio
buttons markupintotheItemTemplate.Eachradiobuttonneedsthesame name attribute,butshouldhavea
uniqueid attribute(incasewewanttoaccessaradiobuttonviaclientsidescript).Afterauserselectsaradio
buttonandpostsbackthepage,thebrowserwillsendbackthevalueoftheselectedradiobuttonsvalue attribute.
Therefore,eachradiobuttonwillneedauniquevalue attribute.Finally,onpostbackweneedtomakesuretoadd
thechecked attributetotheoneradiobuttonthatisselected,otherwiseaftertheusermakesaselectionandposts
back,theradiobuttonswillreturntotheirdefaultstate(allunselected).
Therearetwoapproachesthatcanbetakeninordertoinjectlowlevelmarkupintoatemplate.Oneistodoamix
ofmarkupandcallstoformattingmethodsdefinedinthecodebehindclass.Thistechniquewasfirstdiscussedin
theUsingTemplateFieldsintheGridViewControl tutorial.Inourcaseitmightlooksomethinglike:
<inputtype="radio"id='<%#GetUniqueRadioButtonID(...)%>'
name='SuppliersGroup'value='<%#GetRadioButtonValue(...)%>'.../>

Here,GetUniqueRadioButton andGetRadioButtonValue wouldbemethodsdefinedinthecodebehindclass


thatreturnedtheappropriateid andvalue attributevaluesforeachradiobutton.Thisapproachworkswellfor
assigningtheid andvalue attributes,butfallsshortwhenneedingtospecifythechecked attributevaluebecause
thedatabindingsyntaxisonlyexecutedwhendataisfirstboundtotheGridView.Therefore,iftheGridViewhas
viewstateenabled,theformattingmethodswillonlyfirewhenthepageisfirstloaded(orwhentheGridViewis
explicitlyreboundtothedatasource),andthereforethefunctionthatsetsthechecked attributewontbecalledon
postback.Itsarathersubtleproblemandabitbeyondthescopeofthisarticle,soIllleaveitatthis.Ido,however,
encourageyoutotryusingtheaboveapproachandworkitthroughtothepointwhereyoullgetstuck.Whilesuch
13 of27

anexercisewontgetyouanyclosertoaworkingversion,itwillhelpfosteradeeperunderstandingofthe
GridViewandthedatabindinglifecycle.
Theotherapproachtoinjectingcustom,lowlevelmarkupinatemplate andtheapproachthatwellbeusingfor
thistutorial istoaddaLiteralcontrol tothetemplate.Then,intheGridViewsRowCreated orRowDataBound
eventhandler,theLiteralcontrolcanbeprogrammaticallyaccessedanditsText propertysettothemarkupto
emit.
StartbyremovingtheRadioButtonfromtheTemplateFieldsItemTemplate,replacingitwithaLiteralcontrol.Set
theLiteralcontrolsID toRadioButtonMarkup.

Figure12:AddaLiteralControltotheItemTemplate

Next,createaneventhandlerfortheGridViewsRowCreated event.TheRowCreated eventfiresonceforevery


rowadded,whetherornotthedataisbeingreboundtotheGridView.Thatmeansthatevenonapostbackwhenthe
dataisreloadedfromviewstate,theRowCreated eventstillfiresandthisisthereasonweareusingitinsteadof
RowDataBound (whichfiresonlywhenthedataisexplicitlyboundtothedataWebcontrol).
Inthiseventhandler,weonlywanttoproceedifweredealingwithadatarow.Foreachdatarowwewantto
programmaticallyreferencetheRadioButtonMarkup LiteralcontrolandsetitsText propertytothemarkupto
emit.Asthefollowingcodeshows,themarkupemittedcreatesaradiobuttonwhosename attributeissetto
SuppliersGroup,whoseid attributeissettoRowSelectorX,whereX istheindexoftheGridViewrow,and
whosevalue attributeissettotheindexoftheGridViewrow.
protectedvoidSuppliers_RowCreated(objectsender,GridViewRowEventArgse)
{
if(e.Row.RowType==DataControlRowType.DataRow)
{
//GrabareferencetotheLiteralcontrol
Literaloutput=(Literal)e.Row.FindControl("RadioButtonMarkup")

14 of27

//Outputthemarkupexceptforthe"checked"attribute
output.Text=string.Format(
@"<inputtype=""radio""name=""SuppliersGroup"""+
@"id=""RowSelector{0}""value=""{0}""/>",e.Row.RowIndex)
}
}

WhenaGridViewrowisselectedandapostbackoccurs,weareinterestedintheSupplierID oftheselected
supplier.Therefore,onemightthinkthatthevalueofeachradiobuttonshouldbetheactualSupplierID (rather
thantheindexoftheGridViewrow).Whilethismayworkincertaincircumstances,itwouldbeasecurityriskto
blindlyacceptandprocessaSupplierID.OurGridView,forexample,listsonlythosesuppliersintheUSA.
However,iftheSupplierID ispasseddirectlyfromtheradiobutton,whatstostopamischievoususerfrom
manipulatingtheSupplierID valuesentbackonpostback?Byusingtherowindexasthevalue,andthengetting
theSupplierID onpostbackfromtheDataKeys collection,wecanensurethattheuserisonlyusingoneofthe
SupplierID valuesassociatedwithoneoftheGridViewrows.
Afteraddingthiseventhandlercode,takeaminutetotestoutthepageinabrowser.First,notethatonlyoneradio
buttoninthegridcanbeselectedatatime.However,whenselectingaradiobuttonandclickingoneofthebuttons,
apostbackoccursandtheradiobuttonsallreverttotheirinitialstate(thatis,onpostback,theselectedradiobutton
isnolongerselected).Tofixthis,weneedtoaugmenttheRowCreated eventhandlersothatitinspectstheselected
radiobuttonindexsentfromthepostbackandaddsthechecked="checked" attributetotheemittedmarkupofthe
rowindexmatches.
Whenapostbackoccurs,thebrowsersendsbackthename andvalue oftheselectedradiobutton.Thevaluecanbe
programmaticallyretrievedusingRequest.Form["name"].TheRequest.Form propertyprovidesa
NameValueCollection representingtheformvariables.Theformvariablesarethenamesandvaluesoftheform
fieldsinthewebpage,andaresentbackbythewebbrowserwheneverapostbackensues.Becausetherendered
name attributeoftheradiobuttonsintheGridViewis SuppliersGroup,whenthewebpageispostedbackthe
browserwillsendSuppliersGroup=valueOfSelectedRadioButton backtothewebserver(alongwiththeother
formfields).ThisinformationcanthenbeaccessedfromtheRequest.Form propertyusing:Request.Form
["SuppliersGroup"].
SincewellneedtodeterminetheselectedradiobuttonindexnotonlyintheRowCreated eventhandler,butinthe
Click eventhandlersfortheButtonWebcontrols,letsaddaSuppliersSelectedIndex propertytothecode
behindclassthatreturns1 ifnoradiobuttonwasselectedandtheselectedindexifoneoftheradiobuttonsis
selected.
privateintSuppliersSelectedIndex
{
get
{
if(string.IsNullOrEmpty(Request.Form["SuppliersGroup"]))
return1
else
returnConvert.ToInt32(Request.Form["SuppliersGroup"])
}
}

Withthispropertyadded,weknowtoaddthechecked="checked" markupintheRowCreated eventhandlerwhen


SuppliersSelectedIndex equals e.Row.RowIndex.Updatetheeventhandlertoincludethislogic:
protectedvoidSuppliers_RowCreated(objectsender,GridViewRowEventArgse)
{

15 of27

if(e.Row.RowType==DataControlRowType.DataRow)
{
//GrabareferencetotheLiteralcontrol
Literaloutput=(Literal)e.Row.FindControl("RadioButtonMarkup")
//Outputthemarkupexceptforthe"checked"attribute
output.Text=string.Format(
@"<inputtype=""radio""name=""SuppliersGroup"""+
@"id=""RowSelector{0}""value=""{0}""",e.Row.RowIndex)
//Seeifweneedtoaddthe"checked"attribute
if(SuppliersSelectedIndex==e.Row.RowIndex)
output.Text+=@"checked=""checked"""
//Addtheclosingtag
output.Text+="/>"
}
}

Withthischange,theselectedradiobuttonremainsselectedafterapostback.Nowthatwehavetheabilityto
specifywhatradiobuttonisselected,wecouldchangethebehaviorsothatwhenthepagewasfirstvisited,thefirst
GridViewrowsradiobuttonwasselected(ratherthanhavingnoradiobuttonsselectedbydefault,whichisthe
currentbehavior).Tohavethefirstradiobuttonselectedbydefault,simplychangetheif
(SuppliersSelectedIndex==e.Row.RowIndex) statementtothefollowing:if(SuppliersSelectedIndex
==e.Row.RowIndex||(!Page.IsPostBack&&e.Row.RowIndex==0)).
AtthispointwehaveaddedacolumnofgroupedradiobuttonstotheGridViewthatallowsforasingleGridView
rowtobeselectedandrememberedacrosspostbacks.Ournextstepsaretodisplaytheproductsprovidedbythe
selectedsupplier.InStep4wellseehowtoredirecttheusertoanotherpage,sendingalongtheselected
SupplierID.InStep5,wellseehowtodisplaytheselectedsuppliersproductsinaGridViewonthesamepage.
Note:RatherthanusingaTemplateField(thefocusofthislengthyStep3),wecouldcreateacustom
DataControlField classthatrenderstheappropriateuserinterfaceandfunctionality.The
DataControlField classisthebaseclassfromwhichtheBoundField,CheckBoxField,TemplateField,and
otherbuiltinGridViewandDetailsViewfieldsderive.CreatingacustomDataControlField classwould
meanthatthecolumnofradiobuttonscouldbeaddedjustusingdeclarativesyntax,andwouldalsomake
replicatingthefunctionalityonotherwebpagesandotherwebapplicationssignificantlyeasier.
Ifyouveevercreatedcustom,compiledcontrolsinASP.NET,however,youknowthatdoingsorequiresa
fairamountoflegworkandcarrieswithitahostofsubtletiesandedgecasesthatmustbecarefullyhandled.
Therefore,wewillforgoimplementingacolumnofradiobuttonsasacustomDataControlField classfor
nowandstickwiththeTemplateFieldoption.Perhapswellhavethechancetoexplorecreating,using,and
deployingcustomDataControlField classesinafuturetutorial!

Step4:DisplayingtheSelectedSuppliersProductsinaSeparatePage
AftertheuserhasselectedaGridViewrow,weneedtoshowtheselectedsuppliersproducts.Insome
circumstances,wemaywanttodisplaytheseproductsinaseparatepage,inotherswemightprefertodoitinthe
samepage.LetsfirstexaminehowtodisplaytheproductsinaseparatepageinStep5welllookataddinga
GridViewtoRadioButtonField.aspx todisplaytheselectedsuppliersproducts.
CurrentlytherearetwoButtonWebcontrolsonthepageListProducts andSendToProducts.Whenthe
SendToProducts Buttonisclicked,wewanttosendtheuserto
~/Filtering/ProductsForSupplierDetails.aspx.ThispagewascreatedintheMaster/DetailFilteringAcross
16 of27

TwoPages tutorialanddisplaystheproductsforthesupplierwhoseSupplierID ispassedthroughthequerystring


fieldnamedSupplierID.
Toprovidethisfunctionality,createaneventhandlerfortheSendToProducts ButtonsClick event.InStep3we
addedtheSuppliersSelectedIndex property,whichreturnstheindexoftherowwhoseradiobuttonisselected.
ThecorrespondingSupplierID canberetrievedfromtheGridViewsDataKeys collectionandtheusercanthen
besentto~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID using
Response.Redirect("url").
protectedvoidSendToProducts_Click(objectsender,EventArgse)
{
//Sendtheuserto~/Filtering/ProductsForSupplierDetails.aspx
intsupplierID=
Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value)
Response.Redirect(
"~/Filtering/ProductsForSupplierDetails.aspx?SupplierID="
+supplierID)
}
}

ThiscodeworkswonderfullyaslongasoneoftheradiobuttonsisselectedfromtheGridView.If,initially,the
GridViewdoesnothaveanyradiobuttonsselected,andtheuserclickstheSendToProducts button,
SuppliersSelectedIndex willbe1,whichwillcauseanexceptiontobethrownsince1 isoutoftheindex
rangeoftheDataKeys collection.Thisisnotaconcern,however,ifyoudecidedtoupdatetheRowCreated event
handlerasdiscussedinStep3soastohavethefirstradiobuttonintheGridViewinitiallyselected.
ToaccommodateaSuppliersSelectedIndex valueof1,addaLabelWebcontroltothepageabovethe
GridView.SetitsID propertytoChooseSupplierMsg,itsCssClass propertytoWarning,itsEnableViewState
andVisible propertiesto false,anditsText propertytoPleasechooseasupplierfromthegrid.TheCSSclass
Warning displaystextinared,italic,bold,largefontandisdefinedinStyles.css.Bysettingthe
EnableViewState andVisible propertiesto false,theLabelisnotrenderedexceptforonlythosepostbacks
wherethecontrolsVisible propertyisprogrammaticallysettotrue.

17 of27

Figure13:AddaLabelWebControlAbovetheGridView

Next,augmenttheClick eventhandlertodisplaytheChooseSupplierMsg LabelifSuppliersSelectedIndex is


lessthanzero,andredirecttheuserto~/Filtering/ProductsForSupplierDetails.aspx?
SupplierID=SupplierID otherwise.
protectedvoidSendToProducts_Click(objectsender,EventArgse)
{
//makesureoneoftheradiobuttonshasbeenselected
if(SuppliersSelectedIndex<0)
ChooseSupplierMsg.Visible=true
else
{
//Sendtheuserto~/Filtering/ProductsForSupplierDetails.aspx
intsupplierID=
Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value)
Response.Redirect(
"~/Filtering/ProductsForSupplierDetails.aspx?SupplierID="
+supplierID)
}
}

VisitthepageinabrowserandclicktheSendToProducts buttonbeforeselectingasupplierfromtheGridView.
AsFigure14shows,thisdisplaystheChooseSupplierMsg label.Next,selectasupplierandclickthe
SendToProducts button.Thiswillwhiskyoutoapagethatliststheproductssuppliedbytheselectedsupplier.
Figure15showstheProductsForSupplierDetails.aspx pagewhentheBigfootBreweriessupplierwas
selected.

18 of27

Figure14:TheChooseSupplierMsg LabelisDisplayedifNoSupplierisSelected

19 of27

Figure15:TheSelectedSuppliersProductsareDisplayedinProductsForSupplierDetails.aspx

Step5:DisplayingtheSelectedSuppliersProductsontheSamePage
InStep4wesawhowtosendtheusertoanotherwebpagetodisplaytheselectedsuppliersproducts.
Alternatively,theselectedsuppliersproductscanbedisplayedonthesamepage.Toillustratethis,welladd
anotherGridViewtoRadioButtonField.aspx todisplaytheselectedsuppliersproducts.
SinceweonlywantthisGridViewofproductstodisplayonceasupplierhasbeenselected,addaPanelWeb
controlbeneaththeSuppliers GridView,settingitsID toProductsBySupplierPanel anditsVisible property
tofalse.WithinthePanel,addthetextProductsfortheSelectedSupplier, followedbyaGridViewnamed
ProductsBySupplier.FromtheGridViewssmarttag,choosetobindittoanewObjectDataSourcenamed
ProductsBySupplierDataSource.

20 of27

Figure16:BindtheProductsBySupplier GridViewtoaNewObjectDataSource

Next,configuretheObjectDataSourcetousetheProductsBLL class.Sinceweonlywanttoretrievethose
productsprovidedbytheselectedsupplier,specifythattheObjectDataSourceshouldinvokethe
GetProductsBySupplierID(supplierID) methodtoretrieveitsdata.Select(None)fromthedropdownlists
intheUPDATE,INSERT,andDELETEtabs.

21 of27

Figure17:ConfiguretheObjectDataSourcetoUsetheGetProductsBySupplierID(supplierID) Method

22 of27

Figure18:SettheDropDownListsto(None)intheUPDATE,INSERT,andDELETETabs

AfterconfiguringtheSELECT,UPDATE,INSERT,andDELETEtabs,clickNext.Sincethe
GetProductsBySupplierID(supplierID) methodexpectsaninputparameter,theCreateDataSourcewizard
promptsustospecifythesourcefortheparametersvalue.
Wehaveacoupleofoptionshereinspecifyingthesourceoftheparametersvalue.Wecouldusethedefault
Parameterobject,andprogrammaticallyassignthevalueoftheSuppliersSelectedIndex propertytothe
ParametersDefaultValue propertyintheObjectDataSourcesSelecting eventhandler.Referbacktothe
ProgrammaticallySettingtheObjectDataSource'sParameterValuestutorialforarefresheronprogrammatically
assigningvaluestotheObjectDataSourcesparameters.
Alternatively,wecanuseaControlParameterandrefertotheSuppliers GridViewsSelectedValue property
(seeFigure19).TheGridViewsSelectedValue propertyreturnstheDataKey valuecorrespondingtothe
SelectedIndex property.Inorderforthisoptiontowork,weneedtoprogrammaticallysettheGridViews
SelectedIndex propertytotheselectedrowwhentheListProducts buttonisclicked.Asanaddedbenefit,by
settingtheSelectedIndex,theselectedrecordwilltakeontheSelectedRowStyle definedinthe
DataWebControls Theme(ayellowbackground).

23 of27

Figure19:UseaControlParametertoSpecifytheGridViewsSelectedValueastheParameterSource

Uponcompletingthewizard,VisualStudiowillautomaticallyaddfieldsfortheproductsdatafields.Removeall
buttheProductName,CategoryName,andUnitPrice BoundFields,andchangetheHeaderText propertiesto
Product, Category, andPrice. ConfiguretheUnitPrice BoundFieldsothatitsvalueisformattedasa
currency.Aftermakingthesechanges,thePanel,GridView,andObjectDataSourcesdeclarativemarkupshould
looklikethefollowing:
<asp:Panelrunat="server"ID="ProductsBySupplierPanel"Visible="False">
<h3>
ProductsfortheSelectedSupplier</h3>
<p>
<asp:GridViewID="ProductsBySupplier"runat="server"
AutoGenerateColumns="False"DataKeyNames="ProductID"
DataSourceID="ProductsBySupplierDataSource"EnableViewState="False">
<Columns>
<asp:BoundFieldDataField="ProductName"HeaderText="Product"
SortExpression="ProductName"/>
<asp:BoundFieldDataField="CategoryName"HeaderText="Category"
ReadOnly="True"SortExpression="CategoryName"/>
<asp:BoundFieldDataField="UnitPrice"DataFormatString="{0:c}"
HeaderText="Price"HtmlEncode="False"
SortExpression="UnitPrice"/>
</Columns>
</asp:GridView>
<asp:ObjectDataSourceID="ProductsBySupplierDataSource"runat="server"

24 of27

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

Tocompletethisexercise,weneedtosettheGridViewsSelectedIndex propertytothe
SelectedSuppliersIndex andtheProductsBySupplierPanel PanelsVisible propertytotrue whenthe
ListProducts buttonisclicked.Toaccomplishthis,createaneventhandlerfortheListProducts ButtonWeb
controlsClick eventandaddthefollowingcode:
protectedvoidListProducts_Click(objectsender,EventArgse)
{
//makesureoneoftheradiobuttonshasbeenselected
if(SuppliersSelectedIndex<0)
{
ChooseSupplierMsg.Visible=true
ProductsBySupplierPanel.Visible=false
}
else
{
//SettheGridView'sSelectedIndex
Suppliers.SelectedIndex=SuppliersSelectedIndex
//ShowtheProductsBySupplierPanelpanel
ProductsBySupplierPanel.Visible=true
}
}

IfasupplierhasnotbeenselectedfromtheGridView,theChooseSupplierMsg Labelisdisplayedandthe
ProductsBySupplierPanel Panelhidden.Otherwise,ifasupplierhasbeenselected,the
ProductsBySupplierPanel isdisplayedandtheGridViewsSelectedIndex propertyisupdated.
Figure20showstheresultsaftertheBigfootBreweriessupplierhasbeenselectedandthe ShowProductson
Pagebuttonhasbeenclicked.

25 of27

Figure20:TheProductsSuppliedbyBigfootBreweriesareListedontheSamePage

Summary
AsdiscussedintheMaster/DetailUsingaSelectableMasterGridViewwithaDetailsDetailViewtutorial,records
canbeselectedfromaGridViewusingaCommandFieldwhoseShowSelectButton propertyissettotrue.But
theCommandFielddisplaysitsbuttonseitherasregularpushbuttons,links,orimages.Analternativerow
selectionuserinterfaceistoprovidearadiobuttonorcheckboxineachGridViewrow.Inthistutorialwe
examinedhowtoaddacolumnofradiobuttons.
Unfortunately,addingacolumnofradiobuttonsisntasstraightforwardorsimpleasonemightexpect.Thereisno
builtinRadioButtonFieldthatcanbeaddedattheclickofabutton,andusingtheRadioButtonWebcontrolwithin
aTemplateFieldintroducesitsownsetofproblems.Intheend,toprovidesuchaninterfaceweeitherhaveto
createacustomDataControlField classorresorttoinjectingtheappropriateHTMLintoaTemplateFieldduring
theRowCreated event.
Havingexploredhowtoaddacolumnofradiobuttons,letusturnourattentiontoaddingacolumnofcheckboxes.
26 of27

Withacolumnofcheckboxes,ausercanselectoneormoreGridViewrowsandthenperformsomeoperationon
alloftheselectedrows(suchasselectingasetofemailsfromawebbasedemailclient,andthenchoosingto
deleteallselectedemails).Inthenexttutorialwellseehowtoaddsuchacolumn.
HappyProgramming!

AbouttheAuthor
ScottMitchell,authorofsevenASP/ASP.NETbooksandfounderof4GuysFromRolla.com,hasbeenworkingwith
MicrosoftWebtechnologiessince1998.Scottworksasanindependentconsultant,trainer,andwriter.Hislatest
bookisSamsTeachYourselfASP.NET2.0in24Hours.Hecanbereachedatmitchell@4GuysFromRolla.com. or
viahisblog,whichcanbefoundat http://ScottOnWriting.NET.

SpecialThanksTo
Thistutorialserieswasreviewedbymanyhelpfulreviewers.LeadreviewerforthistutorialwasDavidSuru.
InterestedinreviewingmyupcomingMSDNarticles?Ifso,dropmealineat mitchell@4GuysFromRolla.com.

27 of27

You might also like