I am creating a utility that needs to be flexible enough to use different types of data input by the user. Not just different data, as one user may enter "Rory Gallagher" another "Merle Travis" another "Louis Jordan" and yet another "Gatemouth Brown."
More like one user would enter "Rory Gallagher" another "42" and another both a date (such as 9/8/1956) and an ID value (such as "00034872184").
So the problem is with the GUI: how can I "swap out" the section of the form that prompts them for their input? It seems overkill to create several utilities that are 99% the same. But some "versions" of the app will just need a single "enter some value" label along with a TextBox, while another may need to prompt them for two or even more pieces of information.
I don't want to have an "Input Data" button on the form that would invoke another form, because when the user only needs to enter one single bit of information, that would seem quite bizarre.
I'm thinking the Strategy pattern may be in my future here, but the GUI part is still the conundrum. It would be easier if we were using WPF, but we're not. I guess I could still have a section of the form that I leave large enough to incorporate the "largest" scenario, but is that the best way to go?
I tried the suggestion below:
I added a panel to my form and created a user control via Add | UserControl and tried this:
panel1.Controls.Add(UserControl1);
UserControl1.Dock = DockStyle.Fill;
...but suffered an epic fail ("'PlatypiRUs.UserControl1' is a 'type' but is used like a 'variable'" and "An object reference is required for the non-static field, method, or property 'System.Windows.Forms.Control.Dock.get'")
Epic success now with this:
UserControl1 usr1 = new UserControl1();
panel1.Controls.Add(usr1);
usr1.Dock = DockStyle.Fill;
I would suggest dynamically loading a different user control onto that section of the form. For design-time simplicity, you could put a panel where the dynamic control will be, and then just load it into that panel with docking turned on so it fills the whole panel. Then you can just create a separate user control for each set of data entry fields you need. For instance, if you had a panel control called pnlCustom, you could do the following in the form's load event (or wherever makes sense):
UserControl1 customControl = new UserControl1();
pnlCustom.Controls.Add(customControl);
customControl.Dock = DockStyle.Fill;
In my opinion, this is a Builder pattern.
Basically, think of your form as a "two-step view", which means the following:
Next step is to process the data obviously. For that you have an abstract processor and then concrete implementations for each situation (similar to the first step builder above).
Now it is clear that the UI construction and data processing can be associated 1 to 1, which means the situation is a Factory and it produces the view builder and data processor.
Pseudo code would look like this:
// construct the view.
var factory = Situation.GetCurrentSituationFactory(); //abstract factory.
var uiBuilder = factory.GetUIBuilder(); //abstract builder
var structure = uiBuilder.GetFormStructure([context goes here]); //build view definition
var viewParser = Platform.GetViewParser(); //abstract builder (step 2)
viewParser.ConstructForm([context with form goes here]); //build form UI
// later on, process the input data.
var input = viewPrser.GetInput([context with form goes here]); //input definition
var dataProcessor = factory.GetDataPocessor(); //strategy
dataProcessor.Process(input); //execute processing strategy
In addition, this does not conflict with dynamic controls or anything else you want to use to construct the form. Just implement your abstract concerns correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With