寻找使用WinForms和/或建议重新设计实现的精彩向导示例

Ham*_*jan 5 c# oop wizard winforms

免责声明:在这个问题标签页面中,对话实际上意味着同样的事情,抱歉.我的理由:我不确定最终产品应该是什么样子 - 一堆独立的窗户或者一体化.

我希望改进一个用WinForms烘焙的现有的,难以维护的向导.我需要尝试保持相同的外观和感觉,但我需要清理内部逻辑.共有5个对话框,所有这些对话框都在一个巨大的方法中一个接一个地显示(当然,单击"下一个"按钮之后).来回跳跃的方式是...... 5或6个标签和GOTO!

现在,这个向导是线性的,而不是树.从任何一个对话框/页面,您最多可以访问其他两个对话框/页面.想到了双重链接列表.现在有5 * 4 = 20潜在的状态转换,而只有2*1 + 3*2 = 8它们是有效的.我不必使用gotos.他们通常是邪恶的,在这种情况下他们是 - 很难维持这个...而我正在考虑增加另一个,第6页.为什么原因gotos为在那里是最有可能,因为1.0版正在制作时A)的时间压力,B)这是5年前,所以在当时可用的奇才最好的例子/教程可能不是很大.

现在,向导的大多数页面都要求用户输入.根据用户输入的内容呈现后续页面.如果用户在第3页上说并且决定将后退按钮一直指向1,并且没有更改任何内容,并且点击下一次两次,则状态不应该更改.但是,更改页面x上的内容通常会使页面x + 1上的内容无效.但是,有一些例外,因为页面x上的某些或所有设置可能依赖于页面x-1,x-2等,但页面x + 1,x + 2等不依赖于x一些x.

我希望到目前为止事情是清楚的.我们试图通过为他们默认一些东西来帮助用户.存储事物的方式也不是很好.该对话框具有读/写属性,从/向实际控件复制内容.然后,在主方法中,存在"超级存储",其保存每页的存储.因此,当用户完成页面x并接下来命中时,首先将内容从控件复制到类的本地存储中,然后将这些内容保存到超级存储的相应成员中.

没有使用(对话框/存储器)数组和索引.每个goto目标(标签)都有单独但类似的"创建和填充"逻辑.当页面不再显示时,对话框对象会被丢弃(它们不会被丢弃,但每次要显示它们时,它们都会被重新创建并重新填充.我不相信这是必要的,因为只有需要单个手柄,并且在显示和关闭之后,我相信它可以在相同的状态下再次显示,而不必重新填充控件.如果浪费内存是唯一的问题,我可能会让事情滑落,但事情不是很容易维护,所以我不妨解决这个问题.

我在想:

  1. 将对话框存储在集合中,例如数组,但最好是DLL,因为我只能向前移动1或向后移动1,或者只能移动我列出的两个选项中的一个(对于第一个和最后一个对话框).
  2. 实际上我的标签/页面都扩展了一个共同的抽象类(因为"next","back","exit"按钮,它们的行为对所有人都是通用的).
  3. 每个标签/页面/对话框(出于此问题的目的,同样令人困惑)将具有"指挥"类可见的只读属性.这些属性将来自控件中的值(信息的真正来源),有时属性会稍微按下这些值."指挥"的责任是抓住那些并将它们存放起来.当导体希望用一种方法填充对话框时(让我们称之为"种子").我在这里遇到一些困难,因为每种种子方法的参数都不同.我希望能够利用强类型,以及保持通用性.我怀疑应该给出一些东西.我可以将字典传递给每个种子方法,但感觉太像Pythonic,就像鸭子打字一样.如果我搞砸了,我不知道直到运行时间.此外,对于任何给定的页面,字典的打包和解包更好地始终匹配.这是你进来的地方.
  4. 全局存储可以是一个巨大的字典.我可以遵守规则,保持所有密钥不同,或者根据页面将其名称加上"p1_"到"p5_",只是为了确定.我确信其他方案也存在.拥有巨型字典在最后也很方便 - 用户输入组装的顺序无关紧要,只要它正确完成即可.我也可以拥有一台状态机...... 这也是我在设计中迷失的地方.如果我把东西放在字典中,我将不得不执行很多条件逻辑,例如:如果我在第2页,并且我进行了更改,那么我通常(可能有例外)需要制作旧的默认值任何页面3,4,5无效.根据它的丑陋程度,它可能不比现有的基于goto的设计好多少.

如您所见,有一些挑战.然而,我很有希望,因为通过良好的精灵设计思考是一个肯定是以前重新发明的轮子.也许你可以推荐一个开源的C#/ mono应用程序,它带有一个线性但非平凡的向导,这样我就可以看一下实现.哎呀,甚至Java/Swing也许适合我,只要向导本质上是相似的.WPF对我来说是另一个挑战,我不想有2个问题而不是1个问题.

让我知道你能想到什么.我应该保留这些东西但是尽可能多地清理其他部分吗?随意问的问题.谢谢,

-HG

Joa*_*kim 0

为什么不创建一个类,该类具有每个页面的每个输入字段的属性,并在用户单击向导时跟踪它们,这样您就可以在多个页面之间来回跳转,并且仍然保留已保存的数据。由用户在其会话下添加。您甚至可以在这些页面模型中进行输入验证,因此当用户单击“下一步”时,您可以执行类似的操作

if(!page1model.IsValid)
{
     List<RuleViolation> ruleViolations = page1model.GetRuleViolations();
}
Run Code Online (Sandbox Code Playgroud)

如果我理解你的一些问题的话。

(为了跟踪页面,您可以让页面模型实现相同的接口并创建一个List<IPageModel>或其他东西并向其中添加页面模型)