寻找一个使用 WinForms 实现的优秀向导示例和/或有关设计的建议

发布于 2024-09-13 23:36:00 字数 1539 浏览 7 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

原野 2024-09-20 23:36:00

我有一些 WInForms 向导代码,这是一般体系结构:

在主向导上有 StepList As List(Of baseWizardStep) .. 向导主窗体创建时创建的所有可能步骤的列表。

还有“下一步”、“后退”和“取消”按钮。

与上面的 Alex 一样,有一个基类 (baseWizard) 主窗体,其中包含一个托管当前步骤的用户控件的面板。
每个向导步骤本身都是一个用户控件(继承自 UserControl 的 baseWizardStep)
baseWizardStep 有一些内置事件(ArriveAtStep、ValiateStep、LeaveStep 等)
另外,在 InitliaseStep 子程序中,该子程序将主向导作为参数,并将对主向导表单的引用存储在属性中。
所有步骤都访问主向导以将其数据存储在属性/对象/数据集等中。(数据存储通常在 LeaveStep 事件上完成)
这些步骤通过 ArriveAtStep 事件将数据加载到其控件中。

我有时需要在许多向导之间共享向导步骤,在这种情况下,mainWizard 实现一个接口,并且向导步骤将其主向导属性转换为该接口以访问/存储数据。

我有 2 个事件通过向导进行顶部控制流。

如果您不处理这两个事件中的任何一个,则向导将按顺序从步骤列表中的第一个到最后一个步骤,一次执行一步。

事件 1:如果您处理 ShoudlStepOccur,则此事件允许开发人员决定步骤列表中是否应该发生某个步骤(因此您可以跳过步骤)这似乎以易于理解的隐喻来应对大多数向导。事件为您提供步骤和方向(前进,后退)

事件2:(高级控制)然后主窗体上有另一个事件NavigateToStep,事件为您提供它打算转到的步骤,但您可以将其更改为导航到完全不同的步骤。我们使用它多次循环(例如,在注册课程向导中,我们为每个课程多次执行向导的某些步骤)

我还有一个网格,列出了当前步骤的所有步骤突出显示,用户可以单击以跳过向导。我使用 StepShouldOccur 事件来随时了解要在步骤列表中显示哪些步骤。

一个陷阱:
- 关闭向导时,您必须处理面板中当前没有托管的步骤,并且仅位于步骤列表中,因为否则它们将不会释放其窗口句柄。

不确定这有多大意义,所以我将把它留在那里。

也许有一天我会将这个向导代码放在代码项目或其他东西上,我对它为我们工作的方式感到非常满意。

I have some WInForms wizard code this is the general architecture:

On main wizard have StepList As List(Of baseWizardStep) .. list of all possible steps which is created when the wizard main form is.

Also Next Back and Cancel buttons.

As with Alex above, have a base class (baseWizard) main form with a panel that hosts a user control for the current step.
Each wizard step itself is a user control (Inherits from baseWizardStep that inherits from UserControl)
baseWizardStep has some built in events (ArriveAtStep, ValiateStep, LeaveStep etc..)
Also in an InitliaseStep sub that takes main wizard as a parameter and stores a ref to main wizard form in property.
All the steps access the main wizard to store their data in properties/objects/datasets etc.. (Storing of data is usually done on the LeaveStep event)
The steps load data into their controls on the ArriveAtStep event.

I sometimes need to share wizard steps amongst many wizards, in which case the mainWizard implements an interface and the wizard steps cast their main wizard property to the interface to access/store data.

I have 2 events top control flow through the wizard.

If you don't handle any of these 2 events, then the wizard goes through from 1st in StepList to the last in order one step at a time.

Event 1: If you handle ShoudlStepOccur this event allows developer to decide should a step occur in the list of steps (so you can skip steps) This seems to cope with most wizards in an easy to undserstand metaphor. Event gives you the step and the diurection (Forward, back)

Event 2: (advanced control) THen there is the other event on the main form NavigateToStep, event gives you the step it was intending to go to, but you can change it to navigate to a completely differeent step. We use this to go round in a loop many times (Eg. In the Enrol on a course wizard, we go throurgh some steps of the wizard many times once for each course)

I also have a grid that lists all steps with the current step highlighted and that the user can click on to jump thourgh the wizard. I use the StepShouldOccur event to know which steps to disdplay in the step list at any time.

One gatchas:
-When close wizard, you must dispose the steps that are no currenlty hosted in the panel and just lying around in the StepList becuase they will not releae their windows handles otherwise.

Not sure how much sense that's making so I'm going to leave it there.

Maybe one of these days I'll put this wizard code up on code project or something, I'm quite happy with how it works for us.

默嘫て 2024-09-20 23:36:00

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

if(!page1model.IsValid)
{
     List<RuleViolation> ruleViolations = page1model.GetRuleViolations();
}

如果我理解您的一些问题,您可以执行类似的操作。

(为了跟踪页面,您可以让页面模型实现相同的接口并创建 List 或其他内容并向其中添加页面模型)

why not create a class that has properties for each input field for each page and keep track of them whilst the user clicks through the wizard, that way you would be able to jump back and forth between several pages and still keep the data that has been added by the user under his session. you could even have the input validation in these page models so when a user clicks next you could do something like

if(!page1model.IsValid)
{
     List<RuleViolation> ruleViolations = page1model.GetRuleViolations();
}

this is if I understood some of your problems.

(for keeping track of the pages you could have the page models implement the same interface and create a List<IPageModel> or something and add the page models to it)

若沐 2024-09-20 23:36:00

我投票支持将上层建筑作为传递到每个页面显示的参数。第二个参数是我们进入页面的方向(下一页或上一页)。如果返回则仅显示已存在的数据。如果是“下一页”,则使用先前页面中的数据(在上层建筑中找到)在当前页面中显示适当的数据。如果是第一次显示,该页面还应该包含该信息。如果是,那么它应该提供默认数据,如果不是,那么它可以回收归因于该页面的现有数据(前提是它们与之前页面的数据不矛盾)。状态只是一个数字,在每页之后递增或递减。主代码是一个小的 while 循环,仅显示当前状态的页面并在用户完成页面时更新状态。当用户使用“下一步”离开最后一页时,然后退出循环。

如果有可选页面,那么主代码会变得有点复杂,因为您需要一个逻辑来决定下一页是什么(以及之前的所有页面是什么),但其他一切仍然相同。

I vote for superstructure as a parameter passed to each page as it's being shown. Second parameter would be the direction with which we came to the page (Next or Back). If it's Back then just show the data that already exist. If it's Next then use data from previous pages (found in superstructure) to show appropriate data in current page. The page should also have the information if it is being shown for the first time. If it is then it should provide default data, and if it's not then it can recycle existing data attributed to that page (provided that they don't contradict the data from previous pages). State is just a number, that gets incremented or decremented after each page. Main code is one small while loop that just shows a page for current state and updates a state when user finishes with the page. When user leaves the last page with Next then exit loop.

If there are optional pages then the main code gets a little complicated, because you then need a logic to decide what is next page (and what were all previous pages), but everything else is still the same.

默嘫て 2024-09-20 23:36:00

创建一个 winform,它将托管一个实现接口的用户控件。使所有页面用户控件实现此接口,并控制顶级表单的流程。如果您喜欢这种方法,我可以挖掘一些旧代码来提供更多细节。

Create one winform that will host a user control that implements an interface. make all pages user controls that implement this interface, and control the flow from your top-level form. if you like this approach, i can dig up some old code to give more detail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文