I think you can get closer to what you want to achieve using the free interface. This allows you to chain methods to create and initialize objects in a single expression.
You can get something like this:
Fluent fluent = new Fluent(); var panel = fluent.CreateControlPanel().Children() .AddListBox().SetWidth(200).AddMouseEnterEvent((s, e) => { }).Create() .AddTextBox().SetText("Foo").Create() .GetControlPanel();
The idea is that the method returns an object that allows you to initialize another object. The initializer chain can call the finalizer method (above Create ) on any element, which returns the original object (above Children ) to continue adding other objects or customizing the source.
So, for example, an object of type AddListBox returned to ListBoxSetup , which has a bunch of methods like SetWidth or AddMouseEnterEvent . In this case, Children will also be a special object (like ChildSetup , for example) that has a bunch of methods like AddListBox or AddTextBox . Each of these methods is responsible for creating an object of type ListBox or TextBox or setting properties of the base object that will be created. Fluent will have a method that correctly sets your object structure.
Take a look at this link: http://blog.raffaeu.com/archive/2010/06/26/how-to-write-fluent-interface-with-c-and-lambda.aspx
Here is an example of the base code created as described above. Of course, the code can be significantly improved in its architecture, but it is only for example.
public class Fluent { public ControlPanelCreator CreateControlPanel() { return new ControlPanelCreator(new StackPanel(), this); } } public class ControlPanelCreator { #region Fields private Fluent fluent; private Panel panel; #endregion #region Constructors internal ControlPanelCreator(Panel panel, Fluent fluent) { this.fluent = fluent; this.panel = panel; } #endregion #region Methods public ControlPanelChildrenCreator Children() { return new ControlPanelChildrenCreator(this.panel, this); } #endregion } public class ControlPanelChildrenCreator { #region Fields private ControlPanelCreator panelCreator; private Panel panel; #endregion #region Constructors internal ControlPanelChildrenCreator(Panel panel, ControlPanelCreator panelCreator) { this.panel = panel; this.panelCreator = panelCreator; } #endregion #region Methods public ListBoxCreator AddListBox() { ListBox listBox = new ListBox(); this.panel.Children.Add(listBox); return new ListBoxCreator(listBox, this); } public TextBoxCreator AddTextBox() { TextBox textBox = new TextBox(); this.panel.Children.Add(textBox); return new TextBoxCreator(textBox, this); } public Panel GetControlPanel() { return this.panel; } #endregion } public class ListBoxCreator { #region Fields private ListBox listbox; private ControlPanelChildrenCreator parentCreator; #endregion #region Constructors internal ListBoxCreator(ListBox listBox, ControlPanelChildrenCreator parentCreator) { this.listbox = listBox; this.parentCreator = parentCreator; } #endregion #region Methods public ListBoxCreator SetWidth(int width) { this.listbox.Width = width; return this; } public ListBoxCreator AddMouseEnterEvent(Action<object, MouseEventArgs> action) { this.listbox.MouseEnter += new MouseEventHandler(action); return this; } public ControlPanelChildrenCreator Create() { return this.parentCreator; } #endregion } public class TextBoxCreator { #region Fields private TextBox textBox; private ControlPanelChildrenCreator parentCreator; #endregion #region Constructors internal TextBoxCreator(TextBox textBox, ControlPanelChildrenCreator parentCreator) { this.textBox = textBox; this.parentCreator = parentCreator; } #endregion #region Methods public TextBoxCreator SetText(string defaultText) { this.textBox.Text = defaultText; return this; } public ControlPanelChildrenCreator Create() { return this.parentCreator; } #endregion }