如何有条件地换掉表单中的“用户输入”部分?

时间:2012-06-06 13:34:08

标签: c# winforms design-patterns user-interface

我正在创建一个实用程序,它需要足够灵活,以便使用用户输入的不同类型的数据。不仅仅是不同的数据,因为一个用户可以输入“Rory Gallagher”另一个“Merle Travis”另一个“Louis Jordan”和另一个“Gatemouth Brown”。

更像是一个用户输入“Rory Gallagher”另一个“42”,另一个用户输入日期(例如9/8/1956)和ID值(例如“00034872184”)。

问题在于GUI:如何“换出”提示输入的表单部分?创建几个99%相同的实用程序似乎有点过分。但是应用程序的某些“版本”只需要一个“输入一些值”标签和一个TextBox,而另一个可能需要提示它们两个甚至更多的信息。

我不希望窗体上有一个“输入数据”按钮来调用另一个窗体,因为当用户只需要输入一个信息时,这看起来就很奇怪了。

我认为战略模式可能在我的未来,但GUI部分仍然是难题。如果我们使用WPF会更容易,但我们不是。我想我仍然可以在表格的一部分留下足够大的空间来结合“最大”的情景,但这是最好的方法吗?

更新

我尝试了以下建议:

我在表单中添加了一个面板,并通过Add |创建了一个用户控件UserControl并尝试了这个:

panel1.Controls.Add(UserControl1);
UserControl1.Dock = DockStyle.Fill; 

...但遭遇了史诗般的失败(“'PlatypiRUs.UserControl1'是'类型'但是像'变量'一样使用”和“非静态字段,方法或属性需要对象引用'System.Windows.Forms.Control.Dock.get'“)

再次更新

现在史诗般的成功:

UserControl1 usr1 = new UserControl1();
panel1.Controls.Add(usr1);
usr1.Dock = DockStyle.Fill;

2 个答案:

答案 0 :(得分:4)

我建议动态地将不同的用户控件加载到表单的该部分。为了简化设计时间,您可以将面板放在动态控件所在的位置,然后只需将其装入面板并打开底座,即可填满整个面板。然后,您可以为所需的每组数据输入字段创建单独的用户控件。例如,如果你有一个名为pnlCustom的面板控件,你可以在表单的加载事件中(或者在任何有意义的地方)执行以下操作:

UserControl1 customControl = new UserControl1();
pnlCustom.Controls.Add(customControl);
customControl.Dock = DockStyle.Fill;

答案 1 :(得分:1)

在我看来,这是一个Builder模式。

基本上,将您的表单视为“两步查看”,表示以下内容:

  • 想出定义表单元素的结构(例如文本框,下拉列表等),
  • 实现抽象视图构建器(第一步构建器),以便在不同情况下生成不同的结构(请记住,结构是常见的,不必涉及具体的UI组件,只需定义它们的结构),
  • 为结构必须不同的所有情况实现抽象构建器
  • 然后实现UI构建器,该构建器采用通用结构并构建UI组件。基本上,这个构建器只是将公共结构转换为特定于平台的UI组件(例如win-forms文本框或Html输入)。

下一步是明显处理数据。为此,您有一个抽象处理器,然后针对每种情况进行具体实现(类似于上面的第一步构建器)。

现在很明显,UI构造和数据处理可以1对1关联,这意味着情况是Factory,它会生成视图构建器和数据处理器。

伪代码看起来像这样:

// 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

此外,这不会与动态控件或您要用于构造表单的任何其他内容冲突。只需正确实现您的抽象问题。