我在扩展方法和流畅调用的单一“上下文”与匿名方法相结合方面有很好的经验。
我希望例子会更清楚:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace TcKs.FluentSample {
class FluentSample {
Form CreateDialogBox() {
var frm = new Form();
frm.AddTextField( "Simple text field:" )
.AddTextField( "Advanced text field:", null, txt => txt.BackColor = Color.Red )
.AddTextField( "Complex text field:", lbl => {
lbl.Click += ( _sender, _e ) => MessageBox.Show( lbl, "Some informative text.", "Help" );
lbl.Font = new Font( lbl.Font, FontStyle.Underline );
lbl.Cursor = Cursors.Hand;
},
txt => {
txt.TextChanged += ( _sender, _e ) => txt.BackColor = txt.TextLength > 0 ? SystemColors.Window : Color.Red;
txt.DoubleClick += ( _sender, _e ) => { /* TODO: show lookup dialog */ };
txt.AddErrorProvider();
} )
.AddButton( btn => btn.Click += ( _sender, _e ) => frm.Close() );
return frm;
}
}
// contains standard extension methods for fluent creation of control
static class StandardControlFluentExtensionMethods {
// this extension method create button and add them to parent
public static T AddButton<T>( this T parent ) where T : Control {
return AddButton<T>( parent, (Action<Button>)null );
}
// this extension method create button and add them to parent, then call initMethod
public static T AddButton<T>( this T parent, Action<Button> initButton ) where T : Control {
var button = new Button();
parent.Controls.Add( button );
if ( null != initButton ) { initButton( button ); }
return parent;
}
}
// contains specialized extension methods for fluent creation of control
static class SpecializedControlFluentExtensionMethods {
public static T AddCloseButton<T>( this T parent, Action<Button> initButton ) where T : Control {
return parent.AddButton( btn => {
var frm = btn.FindForm();
if ( null != frm ) { frm.Close(); }
if ( null != initButton ) { initButton( btn ); }
} );
}
}
// contains data-driven extension methods for fluent creation of control
static class DataDrivenControlFluentExtensionMethods {
public static TParent AddTextField<TParent>( this TParent parent, string title ) where TParent : Control {
return AddTextField<TParent>( parent, title, (Action<Label>)null, (Action<TextBox>)null );
}
public static TParent AddTextField<TParent>( this TParent parent, string title, Action<Label> initTitle, Action<TextBox> initEditor ) where TParent : Control {
Label lblTitle = new Label();
// lblTitle .....
if ( null != initTitle ) { initTitle( lblTitle ); }
TextBox txtEditor = new TextBox();
// txtEditor ....
if ( null != initEditor ) { initEditor( txtEditor ); }
return parent;
}
public static TParent AddErrorProvider<TParent>( this TParent parent ) where TParent : Control {
return AddErrorProvider( parent, (Action<ErrorProvider>)null );
}
public static TParent AddErrorProvider<TParent>( this TParent parent, Action<ErrorProvider> initErrorProvider ) where TParent : Control {
// create and/or initilaize error provider
return parent;
}
}
}