Those Darn Checkboxes Posted on September 14, 2007 @ 03:26 csharp
Tonight I spent sometime playing with checkboxes! (Yes I know, I should get out more...) Here's what I learned. Let's say you've got a form with a group of checkboxes. That might look something like this:
Yes I know this is one of the most impressive forms you've ever seen. But let's say that you've got a group of checkboxes and you need to capture which checkboxes are selected. You could wire up an event handler for the "Save" button's click event, then write up a bunch of if-else statements to see which checkboxes are checked and yada yada...
Your code might look something like...
1 if ( checkBox1.Checked ) {}
2 if ( checkBox2.Checked ) {}
3 if ( checkBox3.Checked ) {}
I didn't like this so I wanted to come up with a different way, something that's not so smelly. Here's what I came up with. The ICheckBoxGroup
1 internal interface ICheckBoxGroup< T > {
2 void Add( CheckBox checkbox, T item );
3 IEnumerable< T > GetAllEnabled( );
4 IEnumerable< T > GetAllThatSatisfies( Predicate< CheckBox > condition );
5 }
This allows me to bind a full blown domain object to each checkbox. In this example I'm binding a Sport to each checkbox.
1 ICheckBoxGroup< ISport > group = new CheckBoxGroup< ISport >( );
2 group.Add( checkBox1, Sport.Hockey );
3 group.Add( checkBox2, Sport.BasketBall );
4 group.Add( checkBox3, Sport.FootBall );
5 group.Add( checkBox4, Sport.Golf );
6 group.Add( checkBox5, Sport.Tennis );
When the "Save" button is clicked I'm asking for all the Sports that have been selected like this...
1 StringBuilder builder = new StringBuilder( );
2 foreach ( ISport employee in group.GetAllEnabled( ) ) {
3 builder.AppendFormat( "{0}{1}", employee, Environment.NewLine );
4 }
5 MessageBox.Show( builder.ToString( ) );
The "GetAllEnabled" method is returning an IEnumerable
1 public class CheckBoxGroup< T > : ICheckBoxGroup< T > {
2 public CheckBoxGroup( ) {
3 _checkboxes = new List< CheckBox >( );
4 }
5
6 public void Add( CheckBox checkbox, T item ) {
7 checkbox.Tag = item;
8 checkbox.Text = item.ToString( );
9 _checkboxes.Add( checkbox );
10 }
11
12 public IEnumerable< T > GetAllEnabled( ) {
13 return GetAllThatSatisfies( delegate( CheckBox box ) { return box.Checked; } );
14 }
15
16 public IEnumerable< T > GetAllThatSatisfies( Predicate< CheckBox > condition ) {
17 foreach ( CheckBox checkBox in _checkboxes ) {
18 if ( condition( checkBox ) ) {
19 yield return ( T )checkBox.Tag;
20 }
21 }
22 }
23
24 private readonly IList< CheckBox > _checkboxes;
25 }
Just remember to override ToString on your types otherwise the default implementation will just write the fully qualified name of your type as the text next to your checkbox. I know this example could be greatly improved, but after a bus ride home pondering about this, this was what I could come up. Feel free to toss me your example.
PlayingWithCheckboxes.txt (2.4 KB)