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 MyCheckBox
es 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 MyCheckBox
es.
int topLoc = 12;
int tabIdx = 4;
try
{
foreach(string s in items)
{
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);
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 MyCheckBox
es 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;
}
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
.
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;
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.