26. januar 2006 - 20:11Der er
16 kommentarer og 1 løsning
Dynamiske radiobuttons
Jeg søger den "rigtige" måde at generere radio-buttons dynamisk, og læse værdien ved efterfølgende postback.
Tidligere har jeg lavet dynamiske radio-buttons som en tekst-streng og skrevet dem ud i en Literal, og efterfølgende fanget værdien af dem via Request.Form.
Men nu med .NET 2.0 må jeg hellere skille mig af med mine dårlige vaner, men radio-buttons giver mig lidt problemer:
Jeg har en PlaceHolder som jeg tilføjer HtmlInputRadioButton's og det fungerer fint. Problemerne kommer ved PostBack når jeg vil fange værdien af min radio-button group. Min PlaceHolder har pludselig ingen Controls (radio-buttons) ved PostBack længere, så jeg antager at ViewState ikke holder styr på hvilke Controls der er tilføjet. Så forsøger jeg at fange værdien med Request.Form men de ID'er som jeg har givet mine radio-buttons da jeg oprettede dem er blevet lavet om af ASP.NET til et kryptisk navn - sikkert for at undgå at name-clashes ved flere ContentPages og UserControls.
Mit spørgsmål er simplethen - hvordan laver man en dynamisk radio-button group som man nemt kan læse værdien af ved PostBack.
Jeg er ikke ret glad for at lave en RadioButtonList for min HTML skal kun ende op med et <input type="radio"> tag. Jeg bryder mig ikke om at ASP.NET automatisk laver en table bare for at præsentere en radio-button...
Der er som sådan ikke noget problem - det er bare uhensigtsmæssigt at lave en hel tabel for at lave to radio-buttons. Jeg foretrækker at have min html så semantisk korrekt som muligt ved at styre alt layout med css og undgå unødvendigt markup.
Men det er nu ikke så vigtigt - jeg vil bare foretrække at undgå tabeller hvis det er muligt...
Og så har jeg vist også formuleret mig forkert - min liste skal naturligvis ikke ende op med kun éet radio button tag - det jeg mente var , kun radio tags (i flertal) uden tabeller osv...
Men derfor kan du jo sagtens bruge den indbyggede radiobuttonlist. Du kan bare angive en cssclass. Det vil mildt sagt gøre dit liv nemmere.
Eller skal du lave en placeholder og i codebehind kan du lave HtmlInputRadioButton rb = new HtmlInputRadioButton(); og tilføje dem til placeholderen. På den måde burde de få "normale" id'r fordi de ikke kræver runat server og dermed ikke får obskure navne
1) RadioButtonList renderer sig selv ud som en tabel. Så kan jeg putte nok så mange CssClass'es derpå - tabellen bliver udskrevet alligevel. Dette vil jeg gerne undgå.
2) Det som du beskriver med PlaceHolderen er præcis det jeg har forsøgt, men name atributten ændres når html'en renderer. Jeg setter name til "radiogroup" men i html'en står der noget i stil med name="ctl00$ContentControl$radiogroup".
simpel løsning tilføj et span til siden <span id="test" runat="server"></span>
For at få radiobuttons med normalt id bruger du test.InnerHtml=@"<input type=radio name=radiongroup value=A /><input type=radio name=radiongroup value=B />";
...men så er jeg jo tilbage til min gamle måde at gøre dette på; at skrive radiobuttons ud som en tekst streng. Det er det jeg prøver at forklare øverst i min beskrivelse af problemet.
Mit problem er ikke at jeg ikke ved hvordan jeg kan lave dynamiske radio-buttons. Jeg er bare på jagt efter en smukkere måde at lave dem på end jeg hidtil har gjort.
Tak for de mange kommentarer, men de løsnings-forslag du kommer med er dem som jeg også selv kredser omkring. Jeg havde måske bare forventet at ASP.NET havde en lidt mere elegant tilgang til det...
du får ikke genereret dit kontroltræ ud fra viewstate... du få sat dine properties på kontroller i kontroltræet ud fra viewstate. hvis dine dynamisk indsatte kontroller ikke bliver hængende - er det fordi du ikke indsætter dem hver gang, hvilket er nødvendigt. hvis du f.eks. tilføjer en stak kontroller i en eventhandler, vil det altså være væk næste gang du rammer serveren, hvorfor den placeholder du har lagt dine kontroller ind i vil være tom.
der er lavet implementeringer af "sticky panels" der sørger for at "huske" kontroltræet, du kan hente gratis.
hvis du vil manipulere med den måde en radiobuttonlist renderes, så kan du lave din egen kontrol - og basere den på en radiobuttonlist, og i den overskrive det du gerne vil rette til - f.eks.
public class SpecialRadioButtonList : RadioButtonList { public override void RenderBeginTag(HtmlTextWriter writer) { // din egen implementering - og/eller: base.RenderBeginTag(writer); } }
Tak for forklaringen om viewstate og kontroller. Havde det lidt på fornemmelsen.
Mht at lave min egen kontrol, er en super idé. Tænkte slet ikke på denne mulighed.
Tilbage står jeg nu med spørgsmålet om hvordan jeg fanger værdien af mine dynamisk indsatte radiobuttons ved postback. Jeg ser reelt kun Request.Form som en mulighed efter som kontrollerne forsvinder ved postback. Men den name property jeg sætter på, bliver ændret i den renderede html så jeg ved ikke præcist hvad jeg skal spørge på.
...ville jeg forvente at kunne fange med Request.Form["MyRadioBtn"] men det virker ikke fordi ASP.NET ændrer navnet til name="ctl00$ContentContainer$MyRadioBtn"...
well... mht. det med navngivningen - så skal serverkontroller have et unikt id - altså globalt unikt for hele formen. klikker du f.eks. på en knap på din form - skal det serverside kunne udledes præcis hvilken knap der er klikket på, hvilket ikke ville være muligt hvis der var flere knapper med samme id, så frameworket piller ved dine id's (dog ud fra en navngivningsstandard som nærmest fremgår af de resulterende id's).
mht. til dit aktuelle problem ... så er jeg ikke sikker på at jeg forstår at det med at hente værdierne med en Request.Form[... skulle løse problemet. kontrollerne skal vel stadig være til stede næste gang siden vises.
men... det ville være fint hvis du kunne lægge noget koder herud der illustrerer hvordan du opbygger din form - så ville det være nemmere at komme med et mere konkret bud.
Kontrollerne skal ikke nødvendigvis være til stede igen efter PostBack, ikke lige i mit konkrete tifælde, men det ville naturligvis være rart hvis de var.
Det kan vel laves ved at oprette kontrollerne igen efter PostBack og så læse ud fra Request.Form hvilken værdi der skal sættes (i dette tilfælde, hvilken radiobutton der skal checkes) sådan som man gjorde i ASP Classic.
Tak for hjælpen - smid et svar og du skal få points :-)
Nå ja, glemte helt at skrive at løsningen blev at jeg lavede min egen Kontrol hvor jeg overskrev Render() og fik præsenteret html'en som jeg ville og fik et id ud som ikke var manipuleret af ASP.NET.
Så er det så bare op til mig at sørge for at der ikke er ID'er der koliderer på kryds af ContentPages og UserControls...
hvis du sikerer at kontroltræet retableres efter postback behøver du ikke bikse med request.form og id's - så kan du bare bare iterere over kontrollerne i den container de sidder i. mvh
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.