I have built quite big WinForms application working in industry for a few years. It communicates with many HW devices. Application can be configured to use or not use some of these devices and GUI is modified by this configuration. Now, even more devices (and application possible configurations) are going to be added, so I need to refactor whole application, maybe even write the most of it again and it will be very painful work as it was generally my the first bigger project.
I'm especially afraid of making GUI dependent on application configuration. At this moment, I have many controls in my Form.Designer.cs
file (created in drag&drop designer), and I'm enabling/disabling some buttons, changing text of some labels, adding or removing panels etc in ArrangeControls()
function according to configuration, also in Form.Designer.cs
file.
This function is something like this:
void ArrangeControls(Config hwCfg)
{
if (!hwCfg.dev1&& !hwCfg.dev2&& !hwCfg.dev3&& !hwCfg.dev4)
{
panelDevices.Dispose();
lastPannel = panelTime;
}
else
{
if(hwCfg.dev1)
...
else
...
}
...
}
This is very disgusting solution with few hundreds of lines at this moment and I even need to add more controls and more possible combinations of controls appearance. Can you suggest me some pattern, how to get this problem under control?
-
please don't cross-post : stackoverflow.com/questions/33238800/…gnat– gnat2015年10月20日 20:59:58 +00:00Commented Oct 20, 2015 at 20:59
1 Answer 1
Make the "Configuration-to-GUI" mapping a process of two steps:
let each form provide a set of "low level" features and/or parameters which can be, for example, switched on and and off, or set to a certain value. The feature names/parameter names should typically not reflect a specific device, they should reflect the actual change or meaning in the Form. For example, there might be a feature flag
bool showDevicePanel
, or an integer parametertableFoolastColumnWidth
.implement the mapping which device enables which features completely outside the Form's code, in a central place. You can try to utilize a decision table, or add some methods to your
Config
class, or provide a DSL for defining this mappings, or a mix of those things, whatever suits your needs best.
For example, your Config class might provide a property like
public bool ShowDevicePanel
{
get{return dev1||dev2||dev3||dev4;}
}
and the ArrangeControls
method might look like this:
void ArrangeControls(bool showDevicePanel, /* more parameters as needed*/)
{
if (!showDevicePanel)
{
panelDevices.Dispose();
lastPannel = panelTime;
}
// more arrangements on other parameters
}
That way, you won't need to change the majority of Forms whenever you add a new device. In most cases, it will be sufficient to extend the mapping code and define the specific features and parameters for the new device in one place. Only when a new device needs a completely new feature or kind of parameter in a certain Form, you will have to change that Form.
-
Thank you for your very nice answer. Can you please explain a little more how would you create decision table or how new
Config
class functions could look like? Lets assume that in my Config class, there are only flags of devices usagebool dev1, dev2, dev3
, and myForm
contains for examplebool showLabel, showButton
variables.Majak– Majak2015年10月20日 19:51:54 +00:00Commented Oct 20, 2015 at 19:51 -
@Majak: see my edit.Doc Brown– Doc Brown2015年10月20日 20:06:02 +00:00Commented Oct 20, 2015 at 20:06
Explore related questions
See similar questions with these tags.