使用嵌套的div而不是表或流渲染RadioButtonList

时间:2013-02-17 06:00:09

标签: c# asp.net css webforms radiobuttonlist

我正在C#.NET 3.5中以编程方式生成一个单选按钮列表,并使用RadioButtonList来执行此操作。但是,我觉得非常令人沮丧的是RepeatLayout属性,该属性只能设置为FlowTable

表格用于表格数据,不用于显示表格。并且流量没有帮助,因为它不适合造型。

我真正想要的是一个可以用CSS解决的div嵌套。可以这样做吗?

一些例子来说明我正在谈论的内容以及下面的示例代码。

流量示例

<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 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>

我真正想要的是什么

<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#代码我用来生成列表

我知道无论解决方案是什么,都不会像这样快速简单,但是我把它放在这里,这样你就可以了解我正在使用它的背景。

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);

3 个答案:

答案 0 :(得分:7)

您可能希望使用WebControlAdapter来更改呈现RadioButtonList的方式。

以下是您案例的完整代码:

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--;
    }
}

要将此适配器连接到您的应用程序,您有两个选择。首先是在页面构造函数

中以编程方式执行此操作
var adapters = Context.Request.Browser.Adapters;
var radioButtonListType = typeof(RadioButtonList).AssemblyQualifiedName;
var adapterType = typeof(RadioButtonListAdapter).AssemblyQualifiedName;
if (!adapters.Contains(radioButtonListType))
{
    adapters.Add(radioButtonListType, adapterType);
}

第二个选项是使用.browser文件:

将新的Browser File添加到您的项目中。它将驻留在App_Browsers文件夹中。然后用以下声明替换内容:

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

作为参考,您可以使用ScottGu的帖子ASP.NET 2.0 Control Adapter Architecture中的链接,他们可以在此主题中提供良好的基础。

还有一个开源CSS Friendly Control Adapters项目,它解决了一些默认ASP.NET控件的渲染问题。

答案 1 :(得分:1)

对于.net 4.5&gt;

你几乎可以得到那个html,至少是使用OrderedList(或UnOrdered)的结构,然后使用CSS来获得你喜欢的风格。

<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>

这将呈现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>

设置TextAlign =&#34;对&#34;如果你想要的话,在输入后给你标签。

这就像你可以使用div进行设置一样接近但是然后再用div包围整个列表并设置li和标签css来自该div,你应该设置。

答案 2 :(得分:0)

我认为您应该使用CSS寻找解决方法而不是更改结构。即使我在这种结构上遇到一些问题,但我的设计团队也很容易解决这个问题。