Home > Net >  ASP.NET: Custom CheckBoxList control losing checked state on postback
ASP.NET: Custom CheckBoxList control losing checked state on postback

Time:11-07

I extended the ASP.NET CheckBoxList web control to create a Bootstrap 5 layout version.

The control works fine, but on postback, it loses the checked state. Also, the control's SelectedItem property is null.

I created the same control for the RadioButtonList and it works perfectly. Using DotPeek, I see that both of those inherit the same controls and interfaces, so I can't figure out why the custom RadioButtonList maintains state but the CheckboxList doesn't.

Any ideas? The internet has no useable examples to speak of.

C#

public class Bootstrap5CheckBoxList : CheckBoxList {
        protected override void Render(HtmlTextWriter writer) {
            try {
                var selected = false;

                //var webControl = new WebControl(HtmlTextWriterTag.Div);
                //webControl.ID = ClientID;

                //webControl.RenderBeginTag(writer);

                for (int index = 0; index < Items.Count; index  ) {
                    var item = this.Items[index];

                    //div
                    writer.Indent  ;
                    writer.WriteBeginTag($"div class='form-check {base.CssClass}'");
                    writer.Write('>');
                    writer.WriteLine();

                    //input
                    writer.Indent  ;
                    writer.WriteBeginTag("input");
                    writer.WriteAttribute("id", $"{this.ID}_{index}");
                    writer.WriteAttribute("type", "checkbox");
                    writer.WriteAttribute("name", $"{this.UniqueID}_{index}");

                    var cssClass = "";

                    if (item.Attributes["class"] != null) {
                        cssClass = item.Attributes["class"];
                    }

                    writer.WriteAttribute("class", $"form-check-input {cssClass}");
                    writer.WriteAttribute("value", item.Value);
                    var clientID = this.ClientID;

                    if (item.Selected) {
                        if (selected) {
                            this.VerifyMultiSelect();
                        }
                        selected = true;
                        writer.WriteAttribute("checked", "checked");
                    }

                    if (item.Attributes.Count > 0) {
                        foreach (string key in item.Attributes.Keys) {
                            if (!"class".Equals(key)) {
                                writer.WriteAttribute(key, item.Attributes[key]);
                            }
                        }
                    }
                   
                    if (!item.Enabled)
                        writer.WriteAttribute("disabled", "disabled");

                    if (this.Page != null) {
                        this.Page.ClientScript.RegisterForEventValidation(
                            this.UniqueID,
                            item.Value);
                    }

                    writer.Write('>');
                    writer.WriteEndTag("input");
                    writer.WriteLine();

                    //label
                    writer.WriteBeginTag("label");
                    writer.WriteAttribute("class", "form-check-label");
                    writer.WriteAttribute("for", $"{this.ID}_{index}");

                    writer.Write('>');
                    HttpUtility.HtmlEncode(item.Text, writer);
                    writer.WriteEndTag("label");
                    writer.Indent--;

                    writer.WriteLine();

                    //Close Div
                    writer.WriteEndTag("div");
                    writer.WriteLine();
                    writer.Indent--;


                }

                //webControl.RenderEndTag(writer);

            } catch (Exception ex) {
                throw new Exception(string.Format("{0}.{1}:{2} {3}", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, System.Reflection.MethodBase.GetCurrentMethod().Name, ex.Message, ex.StackTrace));
            }
        }


    }

HTML

<%@ Register TagPrefix="BSControls" Namespace="My.App.classes.custom_controls" Assembly="My.App" %>

<BSControls:Bootstrap5CheckBoxList ID="customCheckList" runat="server">
        <asp:ListItem Value="1">Check 1</asp:ListItem>
        <asp:ListItem Value="2">Check 2</asp:ListItem>
    </BSControls:Bootstrap5CheckBoxList>

CodePudding user response:

looks like you now using html controls, and they don't have automatic viewstate. you would be MUCH better to use a CheckBox list, and format that with bootstrap. And it also FAR better to include that checkbox list in the user control markup, and not write code to inject such controls if possible.

So, plain jane check box (input type = checkbox) as a general rule does not have automatic view state like asp.net controls. So, either drop in a check box list into your user control markup, or you may well have to add code to save/restore the values, since it looks much like you are injecting the "input" control as opposed to using a asp.net checkbox list.

CodePudding user response:

After many trials, I was able to get this working and the answer is surprisingly, or maybe not, simple.

The 'name' attribute is the key and must be in the correct format.

Incorrect Format

writer.WriteAttribute("name", $"{this.UniqueID}_{index}");

Correct Format

writer.WriteAttribute("name", $"{this.UniqueID}${index}");

You must use the $ separator and not an underscore. On postback, the LoadPostData method in CheckBoxList iterates through a collection to retrieve the check state.

  • Related