自定义RadioButtonList在PostBack上丢失了值

时间:2011-05-06 08:10:35

标签: asp.net custom-controls radiobuttonlist

我创建了一个自定义的RadioButtonList,它基于类似的code example for a custom CheckBoxList呈现为无序列表。

但由于某些原因,我在执行回发时未保存所选项目。 我覆盖的唯一方法是渲染方法:

[ToolboxData( "<{0}:ULRadioButtonList runat=server></{0}:ULRadioButtonList>" )]
public class ULRadioButtonList : RadioButtonList {
    protected override void Render( HtmlTextWriter writer ) {
        Controls.Clear();

        string input = "<input id={0}{1}{0} name={0}{2}{0} type={0}radio{0} value={0}{3}{0}{4} />";
        string label = "<label for={0}{1}{0}>{2}</label>";
        string list = "<ul>";

        if ( !String.IsNullOrEmpty( CssClass ) ) {
            list = "<ul class=\"" + CssClass + "\">";
        }

        writer.WriteLine( list );

        for ( int index = 0; index < Items.Count; index++ ) {
            writer.Indent++;
            writer.Indent++;

            writer.WriteLine( "<li>" );

            writer.Indent++;

            StringBuilder sbInput = new StringBuilder();
            StringBuilder sbLabel = new StringBuilder();

            sbInput.AppendFormat(
                input,
                "\"",
                base.ClientID + "_" + index.ToString(),
                base.UniqueID,
                base.Items[index].Value,
                (base.Items[index].Selected ? " checked=\"\"" : "")
            );

            sbLabel.AppendFormat(
                label,
                "\"",
                base.ClientID + "_" + index.ToString(),
                base.Items[index].Text
            );

            writer.WriteLine( sbInput.ToString() );
            writer.WriteLine( sbLabel.ToString() );

            writer.Indent = 1;

            writer.WriteLine( "</li>" );

            writer.WriteLine();

            writer.Indent = 1;
            writer.Indent = 1;
        }

        writer.WriteLine( "</ul>" );
    }
}

我忘了什么吗?如果我使用常规的ASP.NET RadioButtonList,我的选定项目将在回发后保存,因此没有任何其他内容覆盖我的值;它与自定义控件有关。

1 个答案:

答案 0 :(得分:0)

对于此类工作方法,您必须将生成标记中的name(和id)属性与RadioButtonList的属性进行匹配。你的代码中明显的问题是name属性的值 - 它应该附加每个单选按钮的索引,即

 ...
 sbInput.AppendFormat(
            input,
            "\"",
            base.ClientID + "_" + index.ToString(),
            base.UniqueID + index.ToString(),    // <<< note the change here
            base.Items[index].Value,
 ...

在id生成中,也应使用ClientIdSeparator属性而不是“_”。

最后,我必须建议你反对这种控件创作方法,因为它本身就很脆弱,即如果底层ASP.NET控件生成其标记的方式发生了变化,它可能会中断。例如,在ASP.NET中,可以配置客户端ID生成逻辑,因此您的id生成逻辑可能无法正确匹配基本控件生成的原始标记。