标签:
本文的主要写了C#实现向导页的设计方法与注意事项
第一步,建立一个Windows窗体应用程序,取名GuideTest
第二步,将主窗体取名FormMain,将StartPosition属性设定为CenterScreen
第三步,建立三个向导页窗体,分别取名FormGuidePage1、FormGuidePage2、FormGuidePage3,将它们的StartPosition属性都设定为CenterScreen。窗体上面放置四个按钮,分别为上一步(btnPrevious)、下一步(btnNext)、提交(btnSubmit)、取消(btnCancel)。
设立枚举ButtonType,代码如下:
/// <summary> /// 按钮类型 /// </summary> [Flags] public enum ButtonType { /// <summary> /// 默认 /// </summary> DEFAULT = 0, /// <summary> /// 上一步 /// </summary> PREVIOUS = 1, /// <summary> /// 下一步 /// </summary> NEXT = 2, /// <summary> /// 提交 /// </summary> SUBMIT = 4, /// <summary> /// 取消 /// </summary> CANCEL = 8 }
这段代码中的Flag特性,指示可以将枚举作为位域(即一组标志)处理。将这个枚举类型作为参数传入到向导页中,即可控制某一向导页中四个按钮的可见性。
在每个向导页的构造函数中,都要接受ButtonType类型的枚举作为参数,并用这个参数对按钮可见性进行控制。以FormGuidePage1为例:
/// <summary> /// 向导页 /// </summary> /// <param name="buttonType">显示按钮类型</param> public FormGuidePage1(ButtonType buttonType) { InitializeComponent(); //控制按钮可见性 this.btnPrevious.Visible = (buttonType & ButtonType.PREVIOUS) == ButtonType.PREVIOUS; this.btnNext.Visible = (buttonType & ButtonType.NEXT) == ButtonType.NEXT; this.btnSubmit.Visible = (buttonType & ButtonType.SUBMIT) == ButtonType.SUBMIT; this.btnCancel.Visible = (buttonType & ButtonType.CANCEL) == ButtonType.CANCEL; }
而在建立FormGuidePage1类型对象时,就需要将需要显示的按钮,中间用逻辑或运算符隔开,传入到对象中,初始化按钮的可见性。如下面这段代码,意为FormGuidePage1中仅下一步和取消按钮是可见的,上一步和提交按钮是不可见的:
FormGuidePage1 formGuidePage1 = new FormGuidePage1(ButtonType.NEXT | ButtonType.CANCEL);
效果示意:
最后,将向导页上的四个按钮分别返回不同的DialogResult,在我的设计中,上一步返回DialogResult.Yes,下一步返回DialogResult.No,提交返回DialogResult.OK,取消返回DialogResult.Cancel
为FormMain中的按钮btnStart添加Click事件:btnStart_Click,我们可以在这个按钮中实现向导的调用逻辑。下面我用两种方法分别实现了一个场景,即一个包括三个向导页的向导,在第三个向导页上点击“提交”按钮完成向导。
使用goto语句可以很容易地梳理出来一个流程。需要注意的是FormGuidePage1、2、3三个对象的实例要在最开始new出来,并指定每个向导页里按钮的可见性,如第一页没有上一页按钮,最后一页没有下一页按钮,最后一页要有提交按钮等。
标签按向导页顺序分别为STEP1、STEP2、STEP3,点击上一页按钮,跳转到上一个STEP,点击下一页按钮,跳转到下一个STEP,点击提交按钮,直接跳转到最后一个标签END上,点击取消则直接使用return关键字结束函数的调用。在END标签后,实现对数据的处理操作。
/// <summary> /// 向导1 /// </summary> private void Guide1() { FormGuidePage1 formGuidePage1 = new FormGuidePage1(ButtonType.NEXT | ButtonType.CANCEL); FormGuidePage2 formGuidePage2 = new FormGuidePage2(ButtonType.PREVIOUS | ButtonType.NEXT | ButtonType.CANCEL); FormGuidePage3 formGuidePage3 = new FormGuidePage3(ButtonType.PREVIOUS | ButtonType.CANCEL | ButtonType.SUBMIT); DialogResult dialogResult; STEP1: //向导页1 { dialogResult = formGuidePage1.ShowDialog(); switch (dialogResult) { case DialogResult.Yes: //下一步 { goto STEP2; } case DialogResult.Cancel: //取消 { return; } default: { return; } } } STEP2: //向导页2 { dialogResult = formGuidePage2.ShowDialog(); switch (dialogResult) { case DialogResult.Yes: //下一步 { goto STEP3; } case DialogResult.No: //上一步 { goto STEP1; } case DialogResult.Cancel: //取消 { return; } default: { return; } } } STEP3: //向导页3 { dialogResult = formGuidePage3.ShowDialog(); switch (dialogResult) { case DialogResult.No: //上一步 { goto STEP2; } case DialogResult.OK: //提交 { goto END; } case DialogResult.Cancel: //取消 { return; } default: { return; } } } END: { //在这里对各页面内保存数据的处理 MessageBox.Show("提交成功"); } }
另一种连接向导的方式,可以用有限状态机解决。
先创立一个标记向导中各流程节点状态的枚举:
/// <summary> /// 向导状态 /// </summary> public enum GuideStatus { /// <summary> /// 初始状态 /// </summary> START = 0, /// <summary> /// 向导1 /// </summary> GUIDE1, /// <summary> /// 向导2 /// </summary> GUIDE2, /// <summary> /// 向导3 /// </summary> GUIDE3, /// <summary> /// 向导结束 /// </summary> END, /// <summary> /// 流程结束 /// </summary> FINISH }
下面的代码通过不断变换流程节点状态,来控制不同向导页之间的跳转关系。
/// <summary> /// 向导2 /// </summary> private void Guide2() { FormGuidePage1 formGuidePage1 = new FormGuidePage1(ButtonType.NEXT | ButtonType.CANCEL); FormGuidePage2 formGuidePage2 = new FormGuidePage2(ButtonType.PREVIOUS | ButtonType.NEXT | ButtonType.CANCEL); FormGuidePage3 formGuidePage3 = new FormGuidePage3(ButtonType.PREVIOUS | ButtonType.CANCEL | ButtonType.SUBMIT); DialogResult dialogResult; GuideStatus guideStatus = GuideStatus.START; while (guideStatus != GuideStatus.FINISH) { switch (guideStatus) { case GuideStatus.START: //初始状态 { guideStatus = GuideStatus.GUIDE1; } break; case GuideStatus.GUIDE1: //向导1 { dialogResult = formGuidePage1.ShowDialog(); switch (dialogResult) { case DialogResult.Yes: //下一步 guideStatus = GuideStatus.GUIDE2; break; case DialogResult.Cancel: //取消 return; default: return; } } break; case GuideStatus.GUIDE2: //向导2 { dialogResult = formGuidePage2.ShowDialog(); switch (dialogResult) { case DialogResult.Yes: //下一步 guideStatus = GuideStatus.GUIDE3; break; case DialogResult.No: //上一步 guideStatus = GuideStatus.GUIDE1; break; case DialogResult.Cancel: //取消 return; default: return; } } break; case GuideStatus.GUIDE3: //向导3 { dialogResult = formGuidePage3.ShowDialog(); switch (dialogResult) { case DialogResult.No: //上一步 guideStatus = GuideStatus.GUIDE2; break; case DialogResult.OK: //提交 guideStatus = GuideStatus.END; break; case DialogResult.Cancel: //取消 return; default: return; } } break; case GuideStatus.END: { //在这里对各页面内保存数据的处理 MessageBox.Show("提交成功"); guideStatus = GuideStatus.FINISH; } break; } } }
这段代码的功能和方法1中的代码是一样的。
END
标签:
原文地址:http://my.oschina.net/Tsybius2014/blog/511872