Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ASP.NET-Like CheckBox Control for C#

0.00/5 (No votes)
28 Feb 2006 1  
An article on creating a custom control that acts like the "Delete All" checkboxes found on web-based email services.

MyCheckBox image

Introduction

I work at a small company that provides environmental and atmospheric hazard assessments to large government clients. For an application I have developed to allow users to plot structures that represent hazards, I needed a way for the users to delete one or more characteristics from a data record. It seemed to me that the best way to do this would be to mimic the behavior of the Delete All checkbox that comes with ASP.NET and can be found in web-based email programs. In other words, I needed the ability to select individual items in a dynamic list or to select all of the items in the list.

I am not a web developer by any means (except for some very basic HTML and JavaScript; I have spent my career developing desktop applications), and I thought that learning ASP.NET for one small part of my application would be overkill. It also seemed impractical to risk using the standard CheckBox control for anything but the Delete All checkbox. Therefore, I decided to write my own custom control that would allow me to control which items could be set for deletion and not have to worry about the the Delete All checkbox behaving in an unexpected way.

For your enjoyment, then, here is my MyCheckBox control.

Using the code

Since the MyCheckBox is a user control, you can compile it into a DLL and include a reference to it in your project. In my application, I don't actually add an instance of the control to the form at design time, but you can if you need to.

The form on which I have put the MyCheckBoxes in my application is a modal dialog whose consumer calls the AddCheckboxes() method, but here I have set it up as a free-standing form. This method provides the actual formatting of the MyCheckBoxes.

int topLoc = 12;
//Set to next value after highest tab order on form.

int tabIdx = 4;
try
{
    foreach(string s in items)
    {
        //Set the parameters for each of the 

        //MyCheckBoxes that appears on the Form.

        MyCheckBox.MyCheckBox mc = new MyCheckBox.MyCheckBox();
        mc.CanGrow = true;
        mc.CanShrink = true;
        mc.Font = new Font("Microsoft Sans Serif", 
                           10, GraphicsUnit.Point);
        mc.Height = 32;
        mc.Location = new Point(16, topLoc + mc.Height);
        mc.Caption = s.ToString();
        mc.TabStop = true;
        mc.TabIndex = tabIdx;
        mc.BoxCheckedChanged += new 
            MyCheckBox.MyCheckBox.BoxCheckedChangedEventHandler(
            mc_BoxCheckedChanged);
        this.Controls.Add(mc);

        //Set up spacing between boxes.

        topLoc += 28;
        tabIdx++;
    }
}

The topLoc and tabIdx variables are used for formatting and tabbing, respectively. I added 28 to the value of topLoc so that each of the MyCheckBoxes would be equally spaced on the form.

Once the form is loaded, you can try checking the different checkboxes to observe the behavior of the control and its parent form.

When the user clicks the OK button and confirms the deletion, the GetNewList() method is called to collect the non-deleted items for consumption by the parent form.

ArrayList retval = new ArrayList();

try
{
    for(int i = 0; i < this.Controls.Count; i++)
    {
        if(this.Controls[i].GetType() == typeof(MyCheckBox.MyCheckBox))
        {
            MyCheckBox.MyCheckBox mc = 
                      (MyCheckBox.MyCheckBox)this.Controls[i];
            if(!mc.BoxChecked) retval.Add(mc.Caption);
        }
    }
}
catch(Exception e)
{
    MessageBox.Show("Error in " + e.TargetSite + ":  " +
                                  e.Message);
    retval = null;
}
            
//The ArrayList is returned for further 

//processing prior to dismissal of the dialog.

return retval;

It's a fairly simple control, as you can see. I am open to any suggestions as to improvements.

Points of Interest

One feature that I wanted to implement was the ability for the MyCheckBox control to grow or shrink based on the size of the text being displayed in it. The best way I saw to do this was to specify what the control's sizing behavior should be. As you can see from the first code snippet (above), I set the CanShrink and CanGrow properties to true each time I instantiate the control. This way, the control's size will change based on the text that is stored in its Caption property. When calling the set block of the Caption property, I kick off a method called ChangeSize.

//Pad the edges of the control.

int height = (textHeight * 2) + 
             Convert.ToInt32(checkBox.Font.Size);
int width = textWidth + 
            Convert.ToInt32(checkBox.Font.Size * 2) + 
    (inputtext.Length * 10);

bool changeHeight = false;
bool changeWidth = false;

//Both of these are necessary in order 

//to reflect the user's selection

//at design time. For example, the user 

//might want the control to expand

//to fit text that is larger than 

//the designed size but not to shrink below it.


if(CanGrow)
{
    if(height > this.Height) changeHeight = true;
    if(width > this.Width) changeWidth = true;
}
            
if(CanShrink)
{
    if(height < this.Height) changeHeight = true;
    if(width < this.Width) changeWidth = true;
}

if(changeHeight) this.Height = height;
if(changeWidth) this.Width = width;

The method compares the size of the control with the length (in pixels, I think) of the input text. It then shrinks or grows the control based on which options were set on instantiation.

If anyone knows of a better way to test for the size of the input text, since .NET seems to do some sort of internal conversion between points and pixels, please let me know.

History

  • February 27, 2006 - First draft of the article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here