集成传统 Web 应用程序
在 CAB 应用程序中托管现有 Web 应用程序所需要的不仅仅是向智能部件添加一个浏览器控件。客户端集成的要点是所有应用程序(或模块)均已完全集成。这意味着它们可以双向通信和共享信息。直到 CAB 可用,此功能才可行,但解决方案只是说明性的,离可重复使用还差得很远。
但正如上面提到的,现在可以创建 Web 模块来托管任何 Web 应用程序。而且您可以做到这些,无需任何其他模块了解其中的差异。现有模块从未需要改变它们共享信息的方式。
现在我们将逐步介绍构建简单 Web 模块(如图 3 中所示的模块)的过程,这要依赖于由 Smart Client Software Factory 团队提供的指南。我们使用 CAB 服务以及由 Smart Client Software Factory 提供的新的指南包。
![.](https://i-blog.csdnimg.cn/blog_migrate/3b33a324458a40c92fefaa008554b981.png)
图 3 由 Web 模块托管的 Web 应用程序
您需要做的第一件事是新建一个 Web 应用程序或扩展现有的应用程序。本示例概述了创建新 ASP.NET Web 应用程序的步骤。您也可以将其用作修改现有 Web 应用程序的模板。我们使用的过程稍微有点侵略性:您必须将 JScript® 添加到应用程序,而且在设计时通过添加代码利用对象模型与 Web 应用程序通信。
在创建样例 Web 页面(该页面将用作典型 Web 应用程序)后,创建一个 Web 模块。但在这样做之前,必须下载以下必备条件:
• | Guidance Automation Extensions (GAX) |
• | Composite UI Application 指南包(确保在当前解决方案中启用此功能) |
• | Composite UI Application Block |
• | 包含到 CAB 库和 Smart Client Software Factory 的适当引用的简单外壳应用程序 |
• | 包含所有可在某些其他模块和应用程序库中重复使用的公用代码的库项目 |
作为 Smart Client Software Factory 的一部分,诸如 Microsoft.Practices.SmartClient.Web.WebPresenter 和 Microsoft.Practices.SmartClient.Web.WebView 之类的类提供基本探测功能,以便使用 CAB 的事件代理自动映射由 Web 页面触发的事件。从而使任意 Web 模块能够利用内置于 CAB 中的默认通信机制,并能够使所有事件自动流入和流出 Web 页面。Microsoft.Practices.SmartClient.Web.WebView 继承自浏览器控件,可在 Web 模块中重复使用。
请注意,指南包是可选的,并且仅自动提供您的项目中的一些模板代码,如 Smart Client Software Factory 提供的服务。作为替代方法,您也可以从本文下载样例 Web 页面和 Web 模块。
步骤 1:创建 Web 页面 我们将从创建 Web 页面着手,该页面将用作我们的传统 Web 应用程序。
1. | 新建一个 Web 项目或向现有 Web 项目中添加一个新页面。 |
2. | 或者,向可能包含 Web 应用程序所使用的常量的任何公用库中添加引用。 |
3. | 添加一个 HTML 按钮,其“Text”(文本)属性值为“触发上下文已更改的事件(来自 JavaScript)”。 |
4. | 添加一个 ASP.NET 按钮,其“Text”(文本)属性值为“触发上下文已更改的事件(来自 ASP.NET 服务器)”。 |
5. | 添加一个 HTML 文本框,其 id 为“txtCustomerName”。 |
6. | 在页面的 Page_Load 方法中添加以下代码(仅在使用 ASP.NET 服务器控件时才是必需的): ClientScript.RegisterOnSubmitStatement(cstype, Common.Events. ContextChanged, BuildRaiseEvent(Common.Events.ContextChanged)); |
7. | 添加以下 private 方法(也是仅在使用 ASP.NET 服务器控件时才是必需的): private string BuildRaiseEvent(string topic) { StringBuilder sb = new StringBuilder(); sb.Append("window.external.FireEvent(/""); sb.Append(topic); sb.Append("/",0);"); return sb.ToString(); } |
8. | 双击第一个按钮,在 onclick 事件中添加以下代码: window.external.FireEvent("ContextChangedEvent","Param1"); 此代码将触发 Web 页面中的事件,并经由 Smart Client Software Factory 转为 Web 浏览器代码,然后使用事件代理进入智能客户端。 |
9. | 在上一步的 onclick 事件处理程序之后添加以下代码: function EventBroker_Subscribe() { window.external.SubscribeEvent("ContextChangedEvent"); window.external.SubscribeEvent("CustomerContextChangedEvent"); } function EventBroker_ContextChangedEvent() { window.alert("上下文已更改事件:来自 Web 应用程序的问候"); } 通过 Subscribe 事件处理程序,智能客户端可将何时设置事件订阅告诉给 Web 页面(通常在 Web 页面将其自己载入浏览器控件后)。接下来,Web 页面触发并返回到主机,然后调用 SubscribeEvent(Web 页面要订阅的事件)。这样,只要触发该事件,CAB 中的所有全局事件就会从智能客户端流动到 Web 页面。这在 JScript 的 EventBroker_XXX 事件处理程序中捕捉。 |
10. | 添加以下 JScript 函数: function EventBroker_CustomerContextChangedEvent(eventData) { document.getElementById('txtCustomerName').value = eventData.Name; } |
这显示如何将事件数据从智能客户端传递到 Web 页面以及如何在 Web 页面中使用这些数据。
步骤 2:创建 Web 模块 要创建 Web 模块,请首先右键单击解决方案,然后选择“Add”(添加)|“CompositeUI”|“Module”(模块)。在“Add New Project”(添加新项目)对话框中,指定您自己的模块名称。现在,单击“OK”(确定),选择“Shell”(外壳)项目,然后单击“Finish”(完成)。
您会发现已创建了许多新项。一个新的 Web 模块项目已添加到解决方案中。必需的引用(包括 CAB 和 Smart Client Software Factory 库引用)已添加到该 Web 模块项目中。已在新项目中创建了 WorkItems 文件夹,并在该项目中创建了 ModuleInit.cs 文件和类。
步骤 3:新建 WorkItem 新建 WorkItem 相当简单。首先右键单击刚创建的模块中的 WorkItems 文件夹,然后选择“Add”(添加)|“CompositeUI”|“WorkItem”。将名称更改为 WebWorkItem.cs。选择“Shell”(外壳)项目并单击“Finish”(完成)按钮。
此时,您将发现已创建了 WebWorkItem.cs 文件和类。此外,还为 CAB 和 Smart Client Software Factory 添加了 using 指令和必需的引用。
在 ModuleInit 类的 Load 中,添加以下代码:
WorkitemCatalog.RegisterWorkItem<WebWorkItem>();
并将以下 using 指令添加到 ModuleInit.cs 文件的顶部:
using WebModule.WorkItems.WebWorkItem;
步骤 4:新建视图 此步骤解决 Web 页面和智能客户端应用程序(在本例中为 Web 模块)之间的数据交换。
1. | 右键单击 WebWorkItem 文件夹。 |
2. | 选择“Add”(添加)|“CompositeUI”|“View…”(视图…) |
3. | 将名称更改为 WebView,然后单击“Finish”(完成)按钮。这将创建 IWebView 接口、WebPresenter 类和 WebView usercontrol。它们用于实现在整个 Smart Client Software Factory 中使用的典型 MVP 模式。 |
4. | 转到 WebWorkItem 类,然后添加以下代码: public void ShowInView(IShellView view) { WebView webView = this.Items.AddNew<WebView>(); view.MainWorkspace.Show(webView); } 这会将 WebView(一个智能部件)添加到工作项“智能部件”集合的项集合中,并在工作项启动时显示该智能部件。 |
5. | 在设计器模式中打开 WebView UserControl。 |
6. | 从 Smart Client Software Factory 添加 Microsoft.Practices.SmartClient.Web.WebView 控件。 |
7. | 将 Microsoft.Practices.SmartClient.Web.WebView 控件的 Url 属性设置为您刚创建的测试 Web 页面。 |
8. | 转到 WebWorkItem.cs 文件并添加以下 using 指令: using Microsoft.Practices.SmartClient.UI.Themes; |
9. | 打开 WebPresenter 类并添加以下代码: [EventSubscription(Common.Events.ContextChanged, Thread=ThreadOption.UserInterface)] public void OnContextChange(object sender, EventArgs e) { System.Windows.Forms.MessageBox.Show( _ "上下文已更改:来自丰富 UI 组件的问候"); } 这由 Web 页面触发,通过 CAB 事件代理转换为 WebView 代码。 |
10. | 添加以下 using 指令: using Microsoft.Practices.CompositeUI.EventBroker; |
11. | 打开 IWebView 接口并添加以下代码: event WebBrowserDocumentCompletedEventHandler DocumentCompleted; |
12. | 打开 WebPresenter 类并添加图 4 中所示的代码。这允许 Smart Client Software Factory 通过绑定订阅响应 Web 页面加载。加载 Web 页面时,触发 CustomerContextChangedForWebPage 事件。将通过事件代理以 CustomerContextChanged(在 JavaScript 中)形式将其通知给 Web 页面。这是在从智能客户端启动 Web 模块时,上下文或信息从智能客户端流动到 Web 页面的作用,它允许任何 Web 应用程序在响应加载时显示来自智能客户端的任何信息。请注意,发送过程中的覆盖操作并非必要,只是在加载特定事件时引发该事件。 |
13. | 添加以下 using 指令: using System.Threading; using System.Security.Principal; using Microsoft.Practices.CompositeUI.Utility; |
14. | 将以下代码添加到 WebView 类(IWebView 实现): public event WebBrowserDocumentCompletedEventHandler DocumentCompleted { add { this.webView1.DocumentCompleted += value; } remove { this.webView1.DocumentCompleted -= value; } } |
步骤 5:在与外壳应用程序相同的目录中构建和测试 Solution Place WebModule.dll,并将该模块添加到 ProfileCatalog.xml,以便 CAB 模块加载程序服务能够加载它。
最后,按照传递消息时所使用的同一模式,使用事件代理将其传递到其他模块。像启动任何其他 Web 模块一样来启动此 Web 模块。现在,所有全局事件都应从智能客户端流动到 Web 模块,然后再流动回智能客户端。