ASP.NET CheckBoxList Control With Value Attribute

Published on
-
2 min read

ASP.NET server controls is a great way to quickly build a page with dynamic functionality. Even though we do not have much of direct control over the way these controls are rendered, they do a pretty good job and its not very often I get annoyed with them.

Until now.

Generally, I find myself using the .Attributes.Add() method when needing to add additional attributes to certain server controls. No problem! In this case, I wanted to add a “value” attribute that will contain the record ID for that checkbox. I can then use this value within my JavaScript. I would have thought a value attribute would already be there. Its perfectly valid HTML mark-up:

<form>
    <input type="checkbox" name="vehicle" value="Volvo" />
    <input type="checkbox" name="vehicle" value="Volkswagen" />
</form> 

For some reason, when I tried to add my custom attributes after my CheckBoxList was databound (as shown below), the attribute was simply ignored.

NewsCheckList.Items[0].Attributes["value"] = "1";
NewsCheckList.Items[1].Attributes["value"] = "2";
NewsCheckList.Items[2].Attributes["value"] = "3";

So I decided the best way forward would be to create a custom CheckBoxList control that would contain a value attribute. I based my code from an old (but very useful) article that can be found here.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.IO;
using System.Web.UI;
using System.Collections;
using System.ComponentModel;

namespace Site.WebControls
{
    [DefaultProperty("Text"),
    ToolboxData("<{0}:CheckBoxValueList runat=server></{0}:CheckBoxValueList>")]
    public class CheckBoxValueList : CheckBoxList
    {
        protected override void Render(HtmlTextWriter writer)
        {
            StringBuilder sb = new StringBuilder();
            TextWriter tw = new StringWriter(sb);
            
            HtmlTextWriter originalStream = new HtmlTextWriter(tw);
            base.Render(originalStream);
            string renderedText = sb.ToString();

            int start = 0;
            int labelStart = 0;
            int end = renderedText.Length;

            for (int i = 0; i < this.Items.Count; i++)
            {
                StringBuilder itemAttributeBuilder = new StringBuilder();

                end = renderedText.Length;
                start = renderedText.IndexOf("<input", start, end - start);
                labelStart = renderedText.IndexOf("<label", start, end - start);

                this.Items[i].Attributes.Render(new HtmlTextWriter(new StringWriter(itemAttributeBuilder)));

                renderedText = renderedText.Insert(labelStart + 7, itemAttributeBuilder.ToString() + " ");
                renderedText = renderedText.Insert(start + 7, String.Format("{0} value=\"{1}\" ", itemAttributeBuilder.ToString(), this.Items[i].Value));
                start = renderedText.IndexOf("/>", start, renderedText.Length - start);
            }
            
            writer.Write(renderedText);
        }
    }
}

Before you go...

If you've found this post helpful, you can buy me a coffee. It's certainly not necessary but much appreciated!

Buy Me A Coffee

Leave A Comment

If you have any questions or suggestions, feel free to leave a comment. I do get inundated with messages regarding my posts via LinkedIn and leaving a comment below is a better place to have an open discussion. Your comment will not only help others, but also myself.