Render RadioButtonList using nested divs instead of tables or streams

I am creating a switch list programmatically in C # .NET 3.5 and using RadioButtonList to do this. However, something that is very unpleasant for me is the RepeatLayout property, which can only be set to Flow or Table .

Tables are for tabular data, not for displaying forms. And the stream does not help, because it is not suitable for styling.

What I really want is a nest of divs that I can handle with CSS. It can be done?

Some examples illustrating what I'm talking about, and sample code below.

Stream example

 <span id="s1"> <input id="s1_0" type="radio" value="Answer A" name="s1"> <label for="s1_0">Answer A</label> <br> <input id="s1_1" type="radio" value="Answer B" name="s1"> <label for="s1_1">Answer B</label> </span> 

Table example

 <table border="0" id="s1"> <tbody> <tr> <td><input type="radio" value="Answer A" name="s1" id="s1_0"><label for="s1_0">Answer A</label></td> </tr> <tr> <td><input type="radio" value="Answer B" name="s1" id="s1_1"><label for="s1_1">Answer B</label></td> </tr> </tbody> </table> 

What i really want

 <div id="s1"> <div> <input type="radio" value="Answer A" name="s1" id="s1_0"> <label for="s1_0">Answer A</label> </div> <div> <input type="radio" value="Answer B" name="s1" id="s1_1"> <label for="s1_1">Answer B</label> </div> </div> 

C # code that I use to create a list

I know that such a solution will not be as quick and easy as this, but I put it here so that you can understand in what context I use it.

 RadioButtonList rbl = new RadioButtonList { RepeatLayout = RepeatLayout.Table }; foreach (ControlValue cv in MasterControl.listControlValues) { rbl.Items.Add(new ListItem(cv.name, cv.value)); } ControlContainer.Controls.Add(rbl); 
+4
source share
3 answers

You can use the WebControlAdapter to change the way RadioButtonList displays.

Below is the complete code for your case:

 public class RadioButtonListAdapter : WebControlAdapter { protected override void RenderBeginTag(HtmlTextWriter writer) { writer.RenderBeginTag("div"); } protected override void RenderEndTag(HtmlTextWriter writer) { writer.RenderEndTag(); } protected override void RenderContents(HtmlTextWriter writer) { var adaptedControl = (RadioButtonList) Control; int itemCounter = 0; writer.Indent++; foreach (ListItem item in adaptedControl.Items) { var inputId = adaptedControl.ClientID + "_" + itemCounter++; // item div writer.RenderBeginTag("div"); writer.Indent++; // input writer.AddAttribute("type", "radio"); writer.AddAttribute("value", item.Value); writer.AddAttribute("name", adaptedControl.ClientID); writer.AddAttribute("id", inputId); if (item.Selected) { writer.AddAttribute("checked", "checked"); } writer.RenderBeginTag("input"); writer.RenderEndTag(); // label writer.AddAttribute("for", inputId); writer.RenderBeginTag("label"); writer.Write(item.Value); writer.RenderEndTag(); // div writer.Indent--; writer.RenderEndTag(); } writer.Indent--; } } 

To connect this adapter to your application, you have two options. This is first done programmatically in the constructor :

 var adapters = Context.Request.Browser.Adapters; var radioButtonListType = typeof(RadioButtonList).AssemblyQualifiedName; var adapterType = typeof(RadioButtonListAdapter).AssemblyQualifiedName; if (!adapters.Contains(radioButtonListType)) { adapters.Add(radioButtonListType, adapterType); } 

The second option uses the .browser file:

Add a new Browser File to your project. It will be located in the App_Browsers folder. Then replace the contents with the following declaration:

 <browsers> <browser refID="Default"> <controlAdapters> <adapter controlType="System.Web.UI.WebControls.RadioButtonList" adapterType="<your namespace>.RadioButtonListAdapter" /> </controlAdapters> </browser> </browsers> 

As a link, you can use the links from the publication ScottGu ASP.NET 2.0 adapter architecture , they can give a good footer in this thread.

There is also an open CSS project, Friendly Control Adapters , which references some issues with rendering ASP.NET controls by default.

+7
source

For .net 4.5>

You can get almost this html, at least a structure using an OrderedList (or UnOrdered), and then play around with CSS to get your preferred style.

 <asp:RadioButtonList ID="rblTest" runat="server" TextAlign="Left" RepeatDirection="Vertical" RepeatLayout="OrderedList"> <asp:ListItem Value="1" Text="Option 1"></asp:ListItem> <asp:ListItem Value="2" Text="Option 2"></asp:ListItem> <asp:ListItem Value="3" Text="Option 3"></asp:ListItem> </asp:RadioButtonList> 

This will display html:

 <ol id="rblTest"> <li> <label for="rblTest_0">Option 1</label> <input id="rblTest_0" type="radio" name="rblTest" value="0"> </li> <li> <label for="rblTest_1">Option 2</label> <input id="rblTest_1" type="radio" name="rblTest" value="0"> </li> <li> <label for="rblTest_2">Option 2</label> <input id="rblTest_2" type="radio" name="rblTest" value="0"> </li> </ol> 

Setting TextAlign = "Right" gives you a label after entering if you want to.

This is as close as possible to your setup using the div, but then merge the whole list again with the div and set the li and css label from that div, and you should be set.

+1
source

I think you should look for a workaround using CSS, not change the structure. Even I encounter some problems with a similar structure, but my development team easily handles this.

0
source

All Articles