65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Microsoft UIP 块实现 Windows 和 Web 的可重用导航和工作流

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.47/5 (6投票s)

2008年11月21日

CPOL

8分钟阅读

viewsIcon

51677

downloadIcon

332

使用 Microsoft UIP 块实现 Windows 和 Web 的可重用导航和工作流。

目录

引言和目标

所有应用程序 UI 都具有通用逻辑,例如导航到下一个 UI、状态管理和工作流。将所有这三个逻辑都放在代码本身中,会将所有这三个方面与特定 UI 类型(如 Windows 或 Web)绑定在一起。本文将讨论如何使用 UIP 实现 UI 可移植性。

其他应用程序块

  • 验证应用程序块:本文介绍了使用 VAB 进行验证所需的 16 个步骤:验证应用程序块
  • 客户端验证:VAB 的一个缺点是它只进行服务器端验证。本文讨论了如何利用 VAB 进行客户端验证:客户端验证
  • 动态验证:本文根据场景解释了如何构建动态验证:动态验证
  • 策略应用程序块:本文介绍了如何使用策略应用程序块实现即插即用机制:策略应用程序块
  • 日志记录应用程序块:本文介绍了使用日志记录应用程序块的 5 个基本步骤:日志记录应用程序块
  • 数据应用程序:本文介绍了实现数据应用程序块所需的四个步骤:数据应用程序块
  • 异常应用程序块:此应用程序讨论了如何使用异常应用程序块记录项目的异常:异常应用程序块
  • Unity 应用程序块:此应用程序讨论了 DI 和 IOC 中的 Unity 应用程序块:Unity 应用程序块

问题

将导航和工作流与用户界面类型分离本身就是一个挑战。简而言之,我们指的是将导航和工作流放在一个类中,然后使用它来驱动任何类型的 UI,即 Web 或 Windows。下面是该概念的图示表示。

使用 MVC 方法解决问题

一个显而易见的方法是使用 MVC。因此,我们将所有工作流和导航逻辑集中在控制器中,并让控制器驱动 UI 导航,而不管用户界面类型如何。

这在纸面上讨论起来很不错也很理论化。让我们看看如何实际实现。以下是我们希望在 Windows 和 Web 上实现的导航。

以上是 Web 中导航和工作流的外观。

以上是 Windows 应用程序中导航和工作流的外观。因此,我们的目标是创建一个中央导航,可用于 Windows 和 Web。

(UIP) 用户界面进程应用程序块

以下要点是我毫不犹豫地从 UIP 块帮助文档中复制的。用户界面进程 (UIP) 应用程序块 2.0 提供了一个可扩展的框架,用于简化将业务逻辑代码与用户界面分离的过程。您可以使用此块来编写复杂的用户界面导航和工作流流程,这些流程可以在多个场景中重用,并随着应用程序的发展而扩展。UIP 应用程序块解决了用户界面开发中会遇到的一系列特定挑战。这些挑战包括:

  • 导航和工作流控制 - 这不应该嵌入用户界面中,但通常是这样,因为决定下一步显示哪个视图基于业务逻辑。这会导致代码不够优雅且难以管理。
  • 导航和工作流更改 - 使用传统的 UI 技术,重新格式化应用程序的布局(更改页面顺序或添加新页面)非常困难。
  • 状态管理 - 在视图之间传递状态并保持状态一致性很困难,并且对于基于 Windows 的应用程序和 Web 应用程序不同。
  • 保存当前交互的快照 - 您可能希望捕获交互的快照并在其他地方、跨时间、机器或登录边界重新创建它。

下载并安装 UIP 块

您需要做的第一件事是下载 UIP 块。我们将使用 UIP 2.0 版本。http://www.microsoft.com/downloads/details.aspx?FamilyId=98C6CC9D-88E1-4490-8BD6-78092A0F084E&displaylang=en

为 VS 2005 准备 - XSD 修复

安装后,您应该会在“程序文件”中看到 Microsoft for .NET 应用程序。UIP 是为 VS 2003 构建的,这会在 VS 2005 中导致一些严重缺陷。所以我们先来修复它们。您需要从 *UIPConfigSchema.xsd* 文件中删除以下行来编译 UIP 块。

<xs:any maxOccurs="unbounded" minOccurs="0" processContents="skip" /> 

完成后,您就可以在 .NET 2.0 中使用 UIP 了。感谢 tannerel 提供的此修复,帮助了我 http://forums.asp.net/t/713774.aspx

导航图

UIP 块中的所有导航都在配置文件中定义。因此,如果是 Web 应用程序,您需要在 *web.config* 中定义它;如果是 Windows 应用程序,则需要在 *app.config* 中定义它。

首先,我们定义视图名称以及相关的 UI 页面。因此,以下是 Web 应用程序的视图部分。我们有五个视图:*Home.aspx*、*LogOut.aspx*、*CustomerHom.aspx*、*DisplayCustomerWithSales.aspx* 和 *DisplayCustomerWithOutSales.aspx*。

<views>
<view name="HomeView" type="Home.aspx" controller="MyController"/>
<view name="LogOutView" type="LogOut.aspx" controller="MyController"/>
<view name="CustomerView" type="CustomerHom.aspx" controller="MyController"/>
<view name="CustomerSalesView" 
    type="DisplayCustomerWithSales.aspx" controller="MyController"/>
<view name="WithOutSalesView" 
    type="DisplayCustomerWithOutSales.aspx" controller="MyController"/>
</views>

对于 Windows,我们将其与表单链接。*App.config* 文件中的相同视图与 Windows 表单类链接。需要注意的一点是视图与控制器绑定。

<views>
<view name="HomeView"   type="WindowsUIPExample.Home, 
WindowsUIPExample, Version=1.0.0.0, 
Culture=neutral,PublicKeyToken=null" controller="MyController" stayOpen="true"/>

<view name="LogOutView"   type="WindowsUIPExample.LogOut, 
WindowsUIPExample, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null" controller="MyController"/>

<view name="CustomerView" type="WindowsUIPExample.CustomerHome, 
WindowsUIPExample, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null" controller="MyController"/>

<view name="CustomerSalesView" type="WindowsUIPExample.CustomerWithSales, 
WindowsUIPExample, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null" controller="MyController" />

<view name="WithOutSalesView" type="WindowsUIPExample.CustomerWithOutSales, 
WindowsUIPExample, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null" controller="MyController"/>

</view>

现在我们需要使用导航图定义导航。在导航图中,我们需要引用视图名称。因此,我们将 Homeview 设置为起始视图。当我们指定导航值时,视图将根据其所在的节点导航到下一个视图。换句话说,如果状态是 Homeview,我们将导航值设置为 LogOut,它将移动到 LogOutView,即 *LogOut.aspx*。

<navigationGraph startView="HomeView" iViewManager="WindowsFormViewManager" 
  name="MyNavigationGraph" state="State" statePersist="MySession">
<node view="HomeView">
    <navigateTo navigateValue="LogOut" view="LogOutView"/>
    <navigateTo navigateValue="GoCustomerHome" view="CustomerView"/>
</node>

node view="LogOutView">
    navigateTo navigateValue="GoToHome" view="HomeView"/>
/node>
<node view="CustomerView">
    <navigateTo navigateValue="GotoHome" view="HomeView"/>
    <navigateTo navigateValue="WithOutSales" view="WithOutSalesView"/>
    <navigateTo navigateValue="ViewSales" view="CustomerSalesView"/>
</node>
<node view="WithOutSalesView">
    navigateTo navigateValue="GoCustomerHome" view="CustomerView"/>
</node>
<node view="CustomerSalesView">
    navigateTo navigateValue="GoCustomerHome" view="CustomerView"/>
</node>
</navigationGraph>

WebFormView 和 WindowsFormView

如果是 Windows 表单,您需要继承自 WindowsFormView;如果是 Web 应用程序,您需要继承自 WebFormView

通用控制器

以下是神奇的控制器的代码片段。在 UIP 中,控制器应继承自 ControllerBase 类。我们公开了 Web 应用程序或 Windows 应用程序可以调用的方法和函数。这些方法将状态值设置为导航值,然后我们调用导航方法。根据配置文件,控制器会导航到下一个 UI。

public class clsController : ControllerBase
{
    public clsCustomers objCustomers = new clsCustomers();

    public clsController(Navigator objNavigate)
        : base(objNavigate)
    {
        objCustomers.LoadCustomers();
    }
    public void GoToLogOut()
    {
        this.State.NavigateValue = "LogOut";
        this.Navigate();
    }
    public void GoToHome()
    {
        this.State.NavigateValue = "GoToHome";
        this.Navigate();
    }
    public void GoCustomerHome()
    {
        
        this.State.NavigateValue = "GoCustomerHome";
        this.Navigate();
    }
    public void GoToWithOutSales()
    {
        this.State.NavigateValue = "WithOutSales";
        this.Navigate();
    }
    public void GotoWithSales()
    {
        this.State.NavigateValue = "ViewSales";
        this.Navigate();
    }
}

起始页

您始终需要定义一个起始页来启动导航。起始页应该是简单的 Web 或 Windows 应用程序。它不应继承自 WebFormViewWindowsFormView。在起始页中,我们只需调用导航名称。

UIPManager.StartNavigationTask("MyNavigationGraph");

在 UI 中,我们需要获取控制器并调用相应的功能进行导航。例如,在下面的代码片段中,我们调用了 this.controller,对其进行了类型转换,并调用了 GoToHome。通过此操作,页面将过渡到下一个视图,即 WebForm 中的 *Home.aspx* 和 Windows 中的 *Home.cs*。

((clsController)(this.Controller)).GoToHome();

您可以从本文顶部的链接下载上述示例的源代码。

那么您应该使用它吗?UIP 的未来如何?

如果您需要使工作流和导航在 UI 之间具有可移植性,那么可以考虑此解决方案。我说可以考虑。我们在一个项目中实现了 UIP,因为我们需要导航和工作流在 Web 和 Windows 之间保持同步。我们成功地完成了该项目,但过程很艰难。感谢 Tom Hollander,他总结了此块的实际问题:http://blogs.msdn.com/tomholl/archive/2005/03/01/383330.aspx

  • 该块现在已存档,这意味着 Microsoft 不再支持它了。看起来团队已经放弃了它。
  • 很多东西并未完全自动化,因此修改配置文件非常痛苦。
  • 许多架构师仍然认为控制器无法通用化,因为 Web 和 Windows 的行为差异很大。
  • UIP 的应用方式与 ASP.NET 架构相悖。
  • 该方法是 MVC 的,但有些地方造成了混淆。下一版本应该有一个更清晰的实现,针对 Windows 和 Web UI。
  • 没有好的 Web 示例。我认为如果您搜索 Google,您唯一能找到的 UIP Web 示例就是这篇文章……自吹自擂。微软的示例就像玩具……。

源代码

您可以从以下链接获取代码:点击此处

它包含 MyController 项目,其中包含通用控制器,我在 Web 和 Windows 应用程序中都使用了该控制器。

如需进一步阅读,请观看以下面试准备视频和分步视频系列。

© . All rights reserved.