using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Windows.Forms; namespace PlayingWithWinForms { public partial class PhoneNumberView : Form { public PhoneNumberView( ) { InitializeComponent( ); _aggregator = new DelegateAggregator( ); uxPhoneNumberTextBox.Leave += _aggregator.CreateHandler( new FormatPhoneNumberCommand( uxPhoneNumberTextBox ).Execute ); } private readonly IDelegateAggregator _aggregator; } public interface IPhoneNumber { string Number { get; } bool IsValid( ); } internal interface IFormatPhoneNumberCommand { void Execute( ); } internal interface IDelegateAggregator { EventHandler CreateHandler( MethodInvoker command ); } public class PhoneNumber : IPhoneNumber { public PhoneNumber( string number ) { const string expression = @"[\(\)\-\ ]"; _number = ( null != number ) ? Regex.Replace( number, expression, String.Empty ) : string.Empty; } public string Number { get { return _number; } } public bool IsValid( ) { string tenDigitNumberExpression = @"^(\d{10})*$"; return !string.IsNullOrEmpty( _number ) && Regex.IsMatch( _number, tenDigitNumberExpression ); } public override string ToString( ) { return _number; } private readonly string _number; } internal class FormatPhoneNumberCommand : IFormatPhoneNumberCommand { public FormatPhoneNumberCommand( Control control ) { _control = control; } public void Execute( ) { _control.Text = new PhoneNumber( _control.Text ).Number; } private readonly Control _control; } internal class DelegateAggregator : IDelegateAggregator { public DelegateAggregator( ) : this( new List< Delegate >( ) ) {} private DelegateAggregator( IList< Delegate > delegates ) { _delegates = delegates; } public EventHandler CreateHandler( MethodInvoker command ) { _delegates.Add( command ); //return delegate( object sender, EventArgs e ) { command( ); }; // same as line below return delegate { command( ); }; // c# compiler implicitly adds the sender and e params. } private readonly IList< Delegate > _delegates; } }