Wizard Framework:一个自己开发的基于Windows Forms的向导开发框架

最近因项目需要,我自己设计开发了一个基于Windows Forms的向导开发框架,目前我已经将其开源,并发布了一个NuGet安装包。比较囧的一件事是,当我发布了NuGet安装包以后,发现原来已经有一个.NET的向导开发框架了,它叫Microsoft Visual Studio 2013 Wizard Framework。我并没有对其进行深入研究,单从名称上看,该框架是否只能在Visual Studio 2013下使用?上网搜索过,也没发现微软有比较详细的官方资料介绍这个框架。不过无论如何,我还是在此向大家介绍一下我自己开发的这个向导框架,也算是让大家了解一下我的设计思路,以及使大家能够方便地从该框架获益,快捷地在自己的项目中也用上这个向导框架。

有图有真相

话不多说,请先看效果图。为了演示这个框架,我依赖它开发了一个模拟软件安装过程的向导程序。用过类似Install Shield的安装程序的用户,应该对下面的这些对话框比较熟悉吧:

怎么样?看上去还算专业吧?它就是用Wizard Framework开发的。1.0.0版本支持以下功能:

  • 向导对话框可以定制,比如可以自定义对话框的尺寸、Icon、是否支持在线帮助等等
  • 由Windows Forms设计器支持的向导页面设计,开发人员可以像开发一个用户控件一样,直接在Visual Studio中使用拖拽的方式,设计每个页面的界面
  • 每个页面都可以通过CanGoPreviousPage、CanGoNextPage、CanGoFinishPage以及CanGoCancel四个属性,直接设置向导对话框中“上一步”、“下一步”、“完成”和“取消”按钮的状态
  • 每个页面都可以读取其它任何页面所保存的向导模型(WizardModel),通过向导模型获取各个页面的设置参数(比如上面“安装信息汇总”页面中就读取了“软件功能选择”页面的数据并显示出来)
  • 每个页面都可以直接设定其它页面是否在上一步或者下一步可见,比如,在有些情况下,当当前页的某个参数被设置后,我们希望在点“下一步”的时候,能够跳过下一页,而直接进入下下页
  • 每个页面都可以设置自己的Logo
  • 对C# 5.0中async/await的支持,使得面向向导的异步开发模型变得异常简单
  • 支持中文和英文

那么,我该如何获得源代码或者开发包呢?

源代码与NuGet安装包

你可以直接访问Wizard Framework的主页:https://github.com/daxnet/wizard-framework。如果你装有Git客户端的话,可以将本项目克隆到本地:

git clone https://github.com/daxnet/wizard-framework

等克隆结束后,直接在Visual Studio 2013中打开WizardFramework.sln即可(目前Wizard Framework基于.NET Framework 4.5.1开发,所以建议还是用Visual Studio 2013打开)。此时,你可以看到该解决方案包含两个项目:

WizardFramework项目就是该框架的源代码,而InstallerSample是一个Windows Forms应用程序,它使用了WizardFramework开发了一个模拟软件安装过程的向导界面,也就是上面你所看到的界面效果了。你可以修改Program.cs中Main函数的第一条语句,将本地化信息设置为zh-CN或者en-US,来体验该模拟程序在不同区域语言下的界面效果。

如果你希望在自己的Windows Forms项目中使用Wizard Framework,你可以在项目上单击鼠标右键,选择Manage NuGet Packages菜单项,在弹出的对话框中搜索WizardFramework关键字即可:

选中之后,单击“安装”按钮,即可将本向导开发框架添加到你的项目中(注意:建议应用程序是基于.NET Framework 4.5.1开发的)。

使用方法

通过NuGet Package Manager添加了Wizard Framework的引用之后,就可以开始开发向导应用了。基本上可以分三个步骤:开发向导页、开发向导对话框,以及将向导页添加到向导对话框。

开发向导页

要开发一个向导页,只需在Visual Studio的Windows Forms项目上,添加一个用户控件(UserControl),然后使其继承于WizardFramework.WizardPage类即可。此时,Visual Studio编辑器会提示构造函数错误,因为WizardPage类型没有可访问的默认构造函数,这就需要通过自定义的向导页类的构造函数向基类传入参数。以下是WizardPage构造函数的重载,以及各重载构造函数的参数描述。

  • WizardPage(string title, string description, Wizard wizard, IWizardModel model = null)

    • title:用于显示在每个向导页上方黑体标题部分的标题信息
    • description:用于显示在每个向导页上方的向导页描述信息
    • wizard:当前向导页所在的向导对象,一般通过向导页的构造函数参数传入
    • model:当前向导页所使用的数据对象模型
  • WizardPage(string title, string description, Wizard wizard, WizardPageType type)
    • title:用于显示在每个向导页上方黑体标题部分的标题信息
    • description:用于显示在每个向导页上方的向导页描述信息
    • wizard:当前向导页所在的向导对象,一般通过向导页的构造函数参数传入
    • type:当前向导页的类型。分为两种类型:Standard和Expanded。Standard类型的意思是,当显示该向导页时,会在向导对话框的上方显示title和description信息;而对于Expanded类型,则这部分信息不会显示出来,整个页面的设计完全由开发人员自己控制。显然,在上面的示例中,2、3、4、5页都是属于Standard类型的向导页,而1和6页则属于Expanded类型
  • WizardPage(string title, string description, Wizard wizard, IWizardModel model, WizardPageType type)
    • title:用于显示在每个向导页上方黑体标题部分的标题信息
    • description:用于显示在每个向导页上方的向导页描述信息
    • wizard:当前向导页所在的向导对象,一般通过向导页的构造函数参数传入
    • model:当前向导页所使用的数据对象模型
    • type:当前向导页的类型。分为两种类型:Standard和Expanded。Standard类型的意思是,当显示该向导页时,会在向导对话框的上方显示title和description信息;而对于Expanded类型,则这部分信息不会显示出来,整个页面的设计完全由开发人员自己控制。显然,在上面的示例中,2、3、4、5页都是属于Standard类型的向导页,而1和6页则属于Expanded类型

以下是一个向导页的类定义以及构造函数的实现例子:

public partial class FirstPage : WizardPage
{
    public FirstPage(Wizard wizard)
        :base("First Page", "This is the first page.", wizard)
    {
        InitializeComponent();
    }
}

需要注意的是,向导页的构造函数必须是公有(public)的,而且有且只有一个Wizard类型的参数。

向导页中的几个回调函数

在WizardFramework.WizardPage基类中,定义了一些可供Wizard对象调用的回调函数,这些函数将在适当的时候被调用,因此,开发人员可以在这些回调函数中处理自己的逻辑,比如设置是否允许用户点击“下一页”等导航按钮。

  • 【方法】Task ExecuteShowAsync(IWizardPage fromPage)

    • 当Wizard准备显示当前向导页时,调用此方法。该方法以异步方式调用
    • fromPage参数:表示是从哪个向导页导航过来的。比如,当用户点击“下一页”按钮后,下一个向导页将会显示在向导对话框中,通常情况下,fromPage参数是所显示的向导页的上一页
  • 【方法】Task<bool> ExecuteBeforeGoingPreviousAsync()
    • 当用户点击“上一页”按钮后,向导对话框准备进入上一向导页时,调用此方法。该方法以异步方式调用
    • 返回值:返回一个能够返回布尔值的任务对象,此布尔值表示是否真的允许向导对话框进入上一页(True=允许;False=不允许)
  • 【方法】Task<bool> ExecuteBeforeGoingNextAsync()
    • 当用户点击“下一页”按钮后,向导对话框准备进入下一向导页时,调用此方法。该方法以异步方式调用
    • 返回值:返回一个能够返回布尔值的任务对象,此布尔值表示是否真的允许向导对话框进入下一页(True=允许;False=不允许)
  • 【方法】Task<bool> ExecuteBeforeGoingFinishAsync()
    • 当用户点击“完成”按钮后,向导对话框准备进入“完成”向导页时,调用此方法。该方法以异步方式调用
    • 返回值:返回一个能够返回布尔值的任务对象,此布尔值表示是否真的允许向导对话框结束,并向调用方返回DialogResult.OK值(True=允许;False=不允许)
  • 【方法】void PersistValuesToModel()
    • 当向导对话框准备进入其它向导页时,会调用此方法,将当前已显示的向导页界面上的用户设置保存到向导数据模型对象中,下一节将详细介绍这部分内容
  • 【属性】System.Windows.Forms.Control FocusingControl
    • 设置在打开当前向导页时,焦点(Focus)所在的界面控件(即焦点默认应该在哪个控件上)
  • 【属性】System.Drawing.Image Logo
    • 设置当前向导页需要显示在向导对话框右上角的图标

开发人员在自定义自己的向导页面时,可以在子类中重载以上方法或属性,以在不同的时机处理不同的逻辑。详细使用方法,可以参考WizardFramework源代码库自带的InstallerSample示例项目。

向导数据模型

在WizardFramework中,通过引入向导数据模型的概念,来保存每个向导页的用户设置。比如,在InstallerSample示例项目的FeaturePage向导页中,用户可以在界面上选择安装的类型(最小安装、标准安装和完全安装),还可以指定安装路径。这些用户设定都被保存在该向导页的数据模型中,以便其它向导页或者向导对话框读取使用。向导数据模型类的定义,需要实现IWizardModel接口,如下:

public sealed new class Model : IWizardModel
{
    #region Public Properties

    public string SelectedFeature { get; set; }

    public string SelectedFolder { get; set; }

    #endregion Public Properties

    #region Public Methods

    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.AppendLine(string.Format(Resources.SelectedFeaturePattern, SelectedFeature));
        sb.AppendLine(string.Format(Resources.InstallationFolderPattern, SelectedFolder));
        return sb.ToString();
    }

    #endregion Public Methods
}

在数据模型对象中,只需要编写一些与界面控件取值相对应的属性即可。一种推荐的做法是,将向导数据模型类定义在每个向导页的类定义中,也就是作为向导页类的一个内嵌类来定义,类名就简单地使用Model作为类名就行了,为了绕过编译器警告,在声明类的时候加上new关键字。这样做的好处是,今后在其它向导页面或者向导对话框中获取向导模型对象时,有助于提高代码的可读性。

如果向导页需要使用向导数据模型,则需要在构造函数中初始化数据模型对象,如下(注意base构造函数调用的最后一个参数):

public FeaturePage(Wizard wizard)
    : base(Resources.FeaturePageTitle, Resources.FeaturePageDescription, wizard, new Model())
{
    InitializeComponent();
}

并且,需要重载PersistValuesToModel方法,以便将界面控件的值保存到数据模型中:

protected override void PersistValuesToModel()
{
    var selectedFeature = string.Empty;
    if (rbMinimal.Checked)
        selectedFeature = rbMinimal.Text;
    else if (rbStandard.Checked)
        selectedFeature = rbStandard.Text;
    else if (rbFull.Checked)
        selectedFeature = rbFull.Text;

    ModelAs<Model>().SelectedFeature = selectedFeature;
    ModelAs<Model>().SelectedFolder = txtInstPath.Text;
}

当需要在其它页面中,或者通过向导对话框获取向导页的数据模型对象时,可以使用下面的方法:

var model = Wizard.GetWizardModel<FeaturePage.Model>();

此处,通过Wizard对象的GetWizardModel泛型方法,即可得到FeaturePage.Model数据模型对象。

控制向导的导航

在有些场景下,需要根据当前页的某些界面设置,来决定下一页应该导航到哪个向导页。比如,在向导页1中,如果用户点击了某个复选框,那么当用户再点“下一步”按钮时,则跳过页面2,直接进入页面3,否则,则需要跳到页面2。此时,可以调用Wizard对象的SetPageDisplay方法即可。该方法有两个重载:

  • void SetPageDisplay(int pageIndex, WizardPageDisplay display)
    • pageIndex:根据向导页加入到向导对话框的顺序,所对应的向导页索引号
    • display:指定该页是显示(WizardPageDisplay.Show)还是不显示(WizardPageDisplay.Hide)
  • void SetPageDisplay<T>(WizardPageDisplay display)
    • 泛型类型T:指定需要设置显示行为的向导页类型
    • display:指定该页是显示(WizardPageDisplay.Show)还是不显示(WizardPageDisplay.Hide)

开发向导对话框

向导对话框的开发非常简单,只需要新建一个System.Windows.Forms.Form类型,然后使其继承于WizardFramework.Wizard类即可,无需再写更多的代码。当然,如果需要设置一些额外的属性,也可以直接在Visual Studio的属性页中进行设置即可。

初始化向导页,并将向导页添加到向导对话框中

下面的代码展示了向导页初始化并添加到向导对话框的做法,还是非常简单的:

var installer = new FrmInstaller();
installer.Add(installer.CreatePage<WelcomePage>());
installer.Add(installer.CreatePage<LicensePage>());
installer.Add(installer.CreatePage<FeaturePage>());
installer.Add(installer.CreatePage<SummaryPage>());
installer.Add(installer.CreatePage<InstallingPage>());
installer.Add(installer.CreatePage<FinishPage>());

总结

本文介绍了我自己开发的一个向导框架,并介绍了框架的使用。或许,在某些情况下,该框架还是不能满足需求,此时,可以直接把WizardFramework的源代码拉下来进行定制。

时间: 2024-10-16 07:17:46

Wizard Framework:一个自己开发的基于Windows Forms的向导开发框架的相关文章

团队软件开发_基于windows下截屏软件关于NABC框架的特点

经过我们小组数次的激烈讨论,就自己的能力和时间而言,我们小组的初步的计划是开发一款基于windows下的截图软件. 关于这个软件的功能,我们初步的想法如下: 1.能在windows下后台运行,有相应的快捷键,以便随时随地的截取用户所需要的信息: 2.在截屏开始钱前有一个关于形状的选择(如矩形,圆形等),当然,还有我们小组自认为比较好的随意形状的截图: 3.当随意形状截屏时,此软件还有磁性吸附轮廓的功能,以避免鼠标使用时截屏的轮廓不合理情况:

基于 Windows 的应用程序的种类

利用 Visual Studio 可以开发多种不同的基于 Windows 的应用程序.可以创建利用 .NET Framework 的强大功能的 Windows 窗体和 Windows 服务应用程序,或者可以使用 Visual C++ 创建基于 Windows Win32 的应用程序. 原文地址 Windows 窗体 有关 Windows 窗体以及如何在 Visual Studio 中使用它们的更多信息,请参见以下主题. 主题 说明 Windows 窗体入门 提供关于如何创建和开发 Windows

Windows Forms (一)

导读 1.什么是 Windows Forms 2.需要学Windows Forms 么? 3.如何手写一个简单的Windows Forms 程序 4.对上面程序的说明 5.Form 类与Control类 6.Windows Forms 中的事件处理及手写一个带鼠标移动事件的窗体 什么是Windows Forms         通常我们的说的Windows Forms 指的是一类GUI(图形用户界面)程序的统称,Windows Forms 是随着 .NET 1.0 一起发布的,但市面上的 Win

构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 javascript 文件.多终端多浏览器同步测试的开发环境,并且还可以通过 piblish 命令对项目下的文件进行打包操作. 相关连接导航 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一) 执行 $Gulp 时发生了什么 —— 基于 Gulp 的前端集成解决方案(二) 常

基于windows平台的Object-C集成开发环境的搭建

这段时间开始学习IOS开发,对于一些基本环境的设置,查阅资料后搞了出来. 资料链接:http://wenku.baidu.com/view/9ffed817f18583d0496459ca.html 有三个方案可以搭建开发ios的环境: 一,买个苹果电脑,用xcode开发. 二,基于windows搭建一个object-c的开发环境. 三,安装一个苹果虚拟机,在虚拟机里面用xcode开发. 这里第一个和第三个方案就不说了,说说第二个方案. 首先,我们需要在http://www.gnustep.or

一个基于Windows Vista speech API5 3以及WPF技术的语音识别代码

本人小试牛刀,试验了一下用c#.net3.0 WPF技术开发了一个语音识别程序, windows.cs using System;using System.Collections.Generic;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input

一个基于Windows Vista speech API5 3以及WPF技术的语音朗读代码

闲暇无事,利用window SDK 与vs2008,基于Windows Vista speech API5.3以及WPF技术开发了一套语音朗读的代码, 牛刀小试, using System;using System.Collections.Generic;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Docume

.NET Core多平台开发体验[1]: Windows

微软在千禧年推出 .NET战略,并在两年后推出第一个版本的.NET Framework和IDE(Visual Studio.NET 2002,后来改名为Visual Studio),如果你是一个资深的.NET程序员,相信传统的.NET应用的开发方式已经深深地烙印在你的脑子里面..NET Core打来了全新的开发体验,但是开发方式的差异根本不足以成为你快速跨入.NET Core 世界的门槛,因为在.NET Core在很多方面比传统的.NET Framework应用开发要简单.为了消除很多尚未接触过

[.net 面向对象程序设计深入](5).NET MVC 6.0 —— 构建跨平台.NET开发环境(Windows/Mac OS X/Linux)

[.net 面向对象程序设计深入](5).NET MVC 6.0 —— 构建跨平台.NET开发环境(Windows/Mac OS X/Linux) 1.关于跨平台 上篇中介绍了MVC的发展历程,说到.NET 5.0之后更名为 Core 1.0,同样MVC 6.0也是运行在Core 1.0(.NET 5.0)之下. 我们要进行开发和部署基于MVC 6.0的项目,首先要搭建他的开发环境. Core 1.0 是一个支持跨平台框架,下面分别介绍如何在Windows/Mac Os X/Linux下搭建开发