I’ve got an issue where I need to format a phone number as soon as a user clicks away from the phone number text box. So a phone number like (403) 555 - 7777 gets formatted to 4035557777 as soon as focus is removed from the text box. The view looks something like this….

When the phone number (403) 555 - 7777 get’s entered, it should get formatted to 4035557777.

Before: After:

To do this I created a “FormatPhoneNumberCommand” type who’s only purpose is to update the phone number when it is executed. It looks like this:

 1 internal class FormatPhoneNumberCommand : IFormatPhoneNumberCommand 
 2   {
 3       public FormatPhoneNumberCommand( Control control ) 
 4       {
 5           _control = control;
 6       }
 7 
 8       public void Exexute( ) 
 9       {
10           _control.Text = new PhoneNumber( _control.Text ).Number;
11       }
12 
13       private readonly Control _control;
14   }

The “PhoneNumber” type is updating the format of the phone number upon construction, it looks like this:

 1 public class PhoneNumber : IPhoneNumber 
 2   {
 3       public PhoneNumber( string number ) 
 4       {
 5           const string expression = @"[\(\)\-\ ]";
 6           _number = ( null != number ) ? Regex.Replace( number, expression, String.Empty ) : string.Empty;
 7       }
 8 
 9       public string Number 
10       {
11           get { return _number; }
12       }
13 
14       public bool IsValid( ) 
15       {
16           string tenDigitNumberExpression = @"^(\d{10})*$";
17           return !string.IsNullOrEmpty( _number ) &&; Regex.IsMatch( _number, tenDigitNumberExpression );
18       }
19 
20       public override string ToString( ) 
21       {
22           return _number;
23       }
24 
25       private readonly string _number;
26   }

I want the command object to be executed on the text box controls “Leave” event. To capture this event I create a type that’s only purpose to maintain a reference to the command object execute method. I don’t want to declare a local field to hang on to a reference to the command object, so i delegate that task to the DelegateAggregator type. Which is used like this:

1 _aggregator = new DelegateAggregator( );
2 
3   uxPhoneNumberTextBox.Leave += _aggregator.CreateHandler( new FormatPhoneNumberCommand( uxPhoneNumberTextBox ).Execute );

I can now re-use the same delegate aggregator to hold onto references to other command methods, without having to declare a local field for individual command object. The DelegateAggregator type is defined like so…

 1 internal class DelegateAggregator : IDelegateAggregator 
 2   {
 3       public DelegateAggregator( ) : this( new List< Delegate >( ) ) {}
 4 
 5       private DelegateAggregator( IList< Delegate > delegates ) 
 6       {
 7           _delegates = delegates;
 8       }
 9 
10       public EventHandler CreateHandler( MethodInvoker command ) 
11       {
12           _delegates.Add( command );
13           //return delegate( object sender, EventArgs e ) { command( ); }; // same as line below
14           return delegate { command( ); }; // c# compiler implicitly adds the sender and e params.
15       }
16 
17       private readonly IList< Delegate > _delegates;
18   }

The CreateHandler method takes in a “MethodInvoker” delegate as it’s input parameter. The signature for this delegate takes in no input parameters and returns void. The purpose of the DelegateAggregator is to maintain references to delegates, which in this scenario is implicitly maintaining a reference to the command object without having to explicitly declare a local field to refer to the command object.

PhoneNumberView.cs.txt (2.18 KB)

comments powered by Disqus