第 1 章:“长角”应用程序模型
布伦特·雷克托
明智猫头鹰咨询
2003 年 10 月
内容
“Longhorn”应用程序模型的功能
应用程序类
NavigationApplication 类
可扩展应用程序标记语言 (XAML)
总结
为什么我们需要新的应用程序模型? 一个主要原因是,在为 Microsoft windows®® 开发应用程序以及为 Web 开发应用程序之间架起差距。
现在,当你编写 Windows 应用程序时,可以利用 Windows 功能。 应用程序可以提供丰富的响应式用户界面。 可以在客户端计算机上安装应用程序,使应用程序能够在没有网络连接的情况下脱机运行。 Windows 应用程序可以利用客户端计算机的硬件功能。
但是,传统的 Windows 应用程序也有一些缺点。 通常必须安装 Windows 应用程序。 这使得应用程序和任何更新都难以部署。 Windows 应用程序不会在浏览器中运行。 因此,熟悉的 Web UI 范例(例如面向页面的应用程序、直接从一个页面导航到另一个页面、页面历史记录等)不适用于应用程序,除非从头开始创建它们。 Windows 应用程序也不太支持文本,尤其是在尝试在同一页上混合文本和图形时。 创建一个 Windows 应用程序,该应用程序自动在图形周围流动文本,并响应窗口大小和用户对字体和可读性的用户首选项的更改,这是大量的工作。
Web 应用程序也有其独特的优势。 浏览到网页时,浏览器仅下载该页和页面所需的组件。 导航到新页面时,浏览器会下载新页面的要求。 换句话说,浏览器会根据需要逐步下载应用程序。
Web 应用程序的部署是微不足道的。 什么部署? 在服务器上放置必要的应用程序组件,浏览器会根据需要下载它们。 没有部署。
为 Web 应用程序创建 UI 也非常简单。 使用标记声明意图。 例如,假设我需要位于特定位置的表。 我希望图像跟在表格后面。 我希望一些文本在图像周围流动。 在 Web 应用程序中混合文本、图形和媒体(声音和视频)非常简单。
当然,Web 应用程序也有其坏点。 无法在桌面系统上安装 Web 应用程序;因此,应用程序无法脱机运行。 必须始终与服务器建立连接。 某些应用程序操作需要往返服务器,这可降低性能。 与可用的 Windows 控件相比,Web 应用程序选择控件相当基元。 因此,Web 应用程序通常具有较差的交互性。 也很难为 Web 应用程序开发有吸引力的 UI,因为必须使用表来表达任何非简单布局。
目前,设计新应用程序的开发人员需要做出初始、巨大的不可逆决策:应用程序应该是 Web 样式的应用程序还是经典Microsoft Win32® 应用程序? 需要完全独立的编程模型(和技能!),具体取决于所选的应用程序模型。
“Longhorn”允许你使用两个世界最好的开发应用程序。 “Longhorn”应用程序模型采用 Web 应用程序的最佳功能和 Windows 应用程序的最佳功能,并根据托管代码将它们合并到单个统一编程模型中。
开发新应用程序模型的第二个主要原因是提供单个编程模型,该模型可以创建当今使用的各种“应用程序”。 查看你最喜欢的网站之一,例如 CNN 或 MSNBC。 网站是否是传统应用程序? 是否为文档? 它是多媒体演示文稿吗? 在许多情况下,所有三个问题的答案都是肯定的。
当网站包含 UI 元素(如列表框、编辑控件和单选按钮)时,它看起来像呈现 UI 的应用程序。 但是,当它显示图像和文本在图像周围流动时,网站类似于文档。 当它呈现 Flash 内容、图形、音频、视频和动画时,网站似乎是多媒体演示文稿。
当然,这种丰富的网站很难开发。 你需要修补基于 HTML 标记的页面说明,为丰富的 UI Microsoft ActiveX® 控件、嵌入的 Flash 动画,以及可能使用可移植文档格式(PDF)来支持文档。 所有这些技术使用不同的体系结构,提供不同的性能特征,并且需要不同的编程模型和工具。
这通常意味着你必须雇用具有不同技能集的多个开发人员来开发应用程序的每个部分。 然后,开发人员必须将不同的模型合并到单个工作应用程序中。 开发应用程序已足够困难。 调试它通常是一场噩梦。
“Longhorn”提供了一个统一的体系结构,支持这三个层-文档、应用程序和媒体。 是否要使用标记以声明方式创建 UI? 去它。 是否需要使用丰富的 Windows 控件? 然后执行此操作! 是否要以强类型托管语言编写事件处理程序? 你也可以这样做。 是否要根据用户的首选项,将文档中的文本、图形和视频与智能布局和演示文稿混合,并针对客户端系统上的最佳查看和阅读进行优化? 猜猜怎么了? 你也明白这一点。
借助“Longhorn”应用程序模型,可以使用单个编程模型编写应用程序,该模型支持应用程序样式 UI 功能、文本和图形的文档样式呈现以及各种媒体的集成。 此外,还可以使用 Web 应用程序等标记创建 UI。 此外,还可以轻松部署 Web 应用程序(或缺乏部署)。 但是,你仍具有安装应用程序以脱机使用(如 Windows 应用程序)的性能和能力。 应用程序只需重新编译一个源代码库即可作为独立应用程序运行或托管在 Web 浏览器中。 无论哪种情况,应用程序都可以基于表单,例如许多传统的 Windows 应用程序,或基于页面的应用程序,如 Web 应用程序。
“Longhorn”应用程序模型的功能
“Longhorn”应用程序模型定义应用程序是什么:
- 它的入口点
- 其控制流 - 如何从一个页面导航到另一个页面
- 其共享状态和资源
- 应用程序范围的事件
- 它与其他应用程序的隔离
“Longhorn”应用程序模型定义如何部署和维护应用程序:
- 部署为单个文件或多个文件
- 更新、回滚和管理
“Longhorn”应用程序模型定义应用程序的用户体验:
- 零影响安装
- 独立(Windows 样式)或集成在浏览器中
- 联机或脱机运行
- 导航模型
“Longhorn”Web 应用程序
使用“Longhorn”应用程序模型,可以编写类似于当今 Web 应用程序的编写方式的丰富应用程序。 这为 Web 开发人员提供了简单的迁移路径,因为它们编写的代码类似于动态 HTML (DHTML) 网页的代码。 他们可以将标记和脚本放在同一文件中(舒德) 。 他们可以将应用程序的文件部署到 Web 服务器。 应用程序页在 Web 浏览器中运行。
但是,“Longhorn”Web 样式应用程序的对象模型比 DHTML 简单得多。 应用程序代码可以使用完整的“Longhorn”呈现层。 因此,“Longhorn”Web 应用程序可以使用丰富的客户端控件,支持页面上的多媒体和图形,在本地处理事件-基本上是普通客户端应用程序可能执行的操作。 事实上,“Longhorn”Web 应用程序与“Longhorn”桌面应用程序没有太大区别,而不是服务器上的文件:浏览器通常(但不一定)托管 UI;应用程序使用受限权限运行,因为用户尚未将其安装在客户端系统上。
“Longhorn”桌面应用程序
“Longhorn”应用程序模型还定义了如何编写桌面应用程序。 “Longhorn”桌面应用程序 是用户在本地安装的应用程序。 此类应用程序可以联机或脱机运行。 此类应用程序可以向 shell 注册、将图标放在桌面上、向“开始”菜单添加快捷方式等。
桌面应用程序还可以在浏览器窗口或独立窗口中运行。 事实上,桌面应用程序可以支持传统上与 Web 应用程序关联的许多功能,包括:
- 显式定义外部入口点,即可以在任何页面上开始
- 跨页面共享状态
- 处理各种事件,包括页面导航事件
- 控制应用程序流
- 从页面历史记录/旅行导航日志中添加/删除条目
- 启动应用程序窗口
生成“Longhorn”应用程序
若要生成“Longhorn”应用程序,请为应用程序定义对象模型。 可以通过编写代码或以声明方式以编程方式定义模型,方法是使用名为可扩展应用程序标记语言(XAML)的语言编写标记。 将代码和/或标记编译为一个或多个 .NET 程序集、应用程序清单文件和部署清单文件。
(可选)可以将应用程序打包为新的文件格式,称为 容器。 容器中的应用程序文件可以压缩、加密和数字签名。
我在第 2 章中详细介绍了如何构建“Longhorn”应用程序,但目前主要思路是生成“Longhorn”应用程序可提供应用程序的代码、描述应用程序使用的所有组件的应用程序清单,以及告知系统如何安装和维护应用程序的部署清单。
部署“Longhorn”应用程序
“Longhorn”应用程序模型提供轻松、经济高效的应用程序部署。 在最简单的情况下,只需将应用程序文件复制到服务器。 同样,安装应用程序非常简单且无影响。
一个选项根本不是安装应用程序。 用户可以浏览到服务器上的应用程序清单并运行它。 “Longhorn”以增量方式下载应用程序并执行它。 你没有确认要求,没有重新启动要求,也没有 DLL 地狱。 事实上,你甚至不需要管理员权限来安装或运行应用程序。
或者,用户可以浏览到服务器上的应用程序的部署清单并运行它。 “Longhorn”以增量方式下载应用程序,安装并执行它。 默认情况下,所有“Longhorn”应用程序都在称为安全执行环境(SEE)的有限权限环境中运行。
SEE 中运行的应用程序会收到一个受限的权限集,该权限集大致相当于授予与 Internet 区域关联的当前应用程序的权限。 默认情况下,需要比“Longhorn”提供的其他权限的应用程序必须在其应用程序清单中请求这些附加权限。
用户首次运行此类应用程序时,“Longhorn”信任管理器将评估提升的权限请求,向用户通知与授予应用程序权限请求相关的建议风险级别,并为该风险级别提供建议的响应。 当用户允许信任管理器向其请求的权限授予应用程序时,信任管理器将记录此信息。 安装的应用程序的后续执行将继续执行,而不会显示安全警告。
现在,在本地安装应用程序时,它只收到 FullTrust 权限集,因为它从 LocalComputer 区域加载。 代码访问安全性(CAS)对“Longhorn”应用程序的工作方式不同。 本地应用程序(或已安装)应用程序在用户从中下载它而不是自动接收 FullTrust 的站点的安全策略下运行,只是因为它在本地安装。
加载应用程序、组件和资源时,“Longhorn”向公共语言运行时(CLR)安全系统提供证据,例如
- Internet 区域和源站点(来自统一资源标识符 [URI])
- 发布服务器和模块名称(来自部署清单)
然后,CAS 根据应用程序的证据提供基于安全策略的访问权限强制实施。
应用程序的部署清单可以指定“Longhorn”在检查应用程序的新版本时应使用的更新间隔。 当“Longhorn”检测到新版本可用时,它会在后台下载并安装新版本。 下次用户运行应用程序时,她会收到新版本。
安装应用程序时,“Longhorn”会保留以前的版本(如果有)。 如果需要,可以毫不费力地回滚到以前的版本,甚至可以使用“添加/删除程序”完全卸载应用程序。 IT 部门可以将应用程序的安装推送到客户端系统进行免动部署。
指定在编译项目时如何部署应用程序,并且可以通过重新编译来更改部署方案,通常对源代码几乎没有更改或没有更改。
开发人员的程序最初通过 MSAvalon.Windows.Application 类的实例与大部分“Longhorn”应用程序支持进行交互,因此让我们看看该类。
应用程序 类
“Longhorn”程序始终包含应用程序对象的单个实例。 此对象直接或间接派生自 MSAvalon.Windows.Application 类,并执行以下操作:
- 提供应用程序的入口点、封装和范围
- 允许应用程序跨构成应用程序的页面共享代码和状态
- 提供应用程序级事件
- 维护应用程序的窗口集合
- 提供安全模型
- 定义应用程序使用的任何资源
MSAvalon.Windows.Application 类为应用程序提供基本的应用程序支持。 当应用程序需要低开销且不使用页面导航功能时,通常会使用它。 但是,大多数“Longhorn”平台应用程序都使用与 MSAvalon.Windows.NavigationApplication 类密切相关的
此处所示的SimpleApplication1.cs源文件列表演示了如何使用 Application 对象。 EntryClass.Main 方法创建专用应用程序对象,MyApp,并调用其 Run 方法来启动应用程序。 MyApp 类替代 OnStartingUp 方法,该方法在应用程序启动时接收控制。 当系统调用 OnStartingUp 方法时,我调用一个帮助程序方法,该方法创建应用程序的主窗口,向窗口添加一些文本,并显示窗口。
SimpleApplication1.cs
using System;
using MSAvalon.Windows;
using MSAvalon.Windows.Controls;
using MSAvalon.Windows.Media;
namespace IntroLonghorn {
public class MyApp : MSAvalon.Windows.Application {
MSAvalon.Windows.Controls.SimpleText txtElement;
MSAvalon.Windows.Window mainWindow;
protected override void OnStartingUp (StartingUpCancelEventArgs e) {
base.OnStartingUp (e);
CreateAndShowMainWindow ();
}
private void CreateAndShowMainWindow () {
// Create the application's main window
mainWindow = new MSAvalon.Windows.Window ();
// Add a dark red, 14 point, "Hello World!" text element
txtElement = new MSAvalon.Windows.Controls.SimpleText ();
txtElement.Text = "Hello World!";
txtElement.Foreground = new
MSAvalon.Windows.Media.SolidColorBrush (Colors.DarkRed);
txtElement.FontSize = new FontSize (14,
FontSizeType.Point);
mainWindow.Children.Add (txtElement);
mainWindow.Show ();
}
}
internal sealed class EntryClass {
[System.STAThread]
private static void Main () {
MyApp app = new MyApp ();
app.Run ();
}
}
}
我使用以下命令行将SimpleApplication1.cs源代码编译为可执行应用程序。 可能需要调整引用程序集的路径。
csc /r:C:\WINDOWS\Microsoft.NET\Windows\v6.0.4030\PresentationCore.dll
/r:C:\WINDOWS\Microsoft.NET\Windows\v6.0.4030\PresentationFramework.dll
/r:C:\WINDOWS\Microsoft.NET\Windows\v6.0.4030\WindowsBase.dll
SimpleApplication1.cs
Application 类包含许多其他有用的属性、方法和事件。 例如,应用程序类可以替代 OnShuttingDown 虚拟方法以提供自定义关闭行为。 应用程序类还提供 StartingUp 和 ShutdowntingDown 事件,以便其他类可以注册启动和关闭通知。 Shutdown 方法允许以编程方式启动应用程序的关闭。
你可能想要从源代码中的多个位置引用应用程序对象。 因此,Application 类提供返回对应用程序对象的引用的 Current 静态属性。 以下代码片段使用 Current 属性查找应用程序对象并注册关闭事件通知:
MyApp app = (MyApp) MSAvalon.Windows.Application.Current;
app.ShuttingDown += new
Application.ShuttingDownEventHandler (ShutDownHandler);
§
private static void
ShutDownHandler (object sender, MSAvalon.Windows.ShuttingDownEventArgs e) {
§
}
NavigationApplication 类
如果希望对应用程序提供导航支持,通常会使用 MSAvalon.Windows.Navigation.NavigationApplication 类,该类扩展了 MSAvalon.Windows.Application 类。 尽管可以在不使用 NavigationApplication 类的情况下生成基于导航的应用程序,但使用该类可为应用程序提供以下附加功能:
- 简化基于导航的应用程序的编写;通常不需要对类进行子类
- 确定连接何时可用
- 提供导航事件(例如 导航、NavigationProcess、Navigated、NavigationError、LoadCompleted,以及 已停止),在应用程序的任何窗口中发生相应事件时触发
- 跨页面共享状态
- 为跨页共享的属性值提供容器
- 实现默认打开初始窗口的策略
在外部,导航应用程序的用户只能导航到应用程序定义的明确入口点。 但是,在内部,开发人员通过挂钩事件控制导航。 可以确定窗口或框架何时尝试导航到新页面,以及导航何时完成。 可以取消或重定向任何导航。 可以找出目标页的标识。 可以处理导航错误。
熟悉的导航模型使应用程序易于使用。 导航应用程序提供类似于 Web 的行为。 应用程序可以使用超链接、提供“转发”和“后退”按钮、显示收藏夹列表和维护页面历史记录。 “Longhorn”NavigationApplication 类和相关类提供了对此类功能的所有支持。
导航应用程序是联机还是脱机工作,无论浏览器是托管应用程序还是应用程序作为独立运行,它的工作方式相同。 此外,你已完全控制此 Weblike 行为。 可以根据需要自定义用户体验。 可以插入、删除和修改 Travelog 条目,以控制前进和后退操作的位置。 可以定义历史记录中记录哪些页面(入口点)。
导航应用程序通常创建 MSAvalon.Windows.Navigation.NavigationWindow 类的一个或多个实例。 此处所示的SimpleApplication2.cs列表演示了这些类的使用。 此列表与SimpleApplication1.cs相同,只不过它使用 NavigationApplication 和 NavigationWindow 类。
SimpleApplication2.cs
using System;
using MSAvalon.Windows;
using MSAvalon.Windows.Controls;
using MSAvalon.Windows.Media;
using MSAvalon.Windows.Navigation;
namespace IntroLonghorn {
public class MyApp : MSAvalon.Windows.Navigation.NavigationApplication {
protected override void OnStartingUp (StartingUpCancelEventArgs e) {
base.OnStartingUp (e);
CreateAndShowMainWindow ();
}
private void CreateAndShowMainWindow () {
// Create the application's main window
mainWindow = new MSAvalon.Windows.Navigation.NavigationWindow ();
// Fill window with appropriate controls
§
// Show the window
mainWindow.Show ();
}
}
internal sealed class EntryClass {
[System.STAThread]
private static void Main () {
MyApp app = new MyApp ();
app.Run ();
}
}
}
到目前为止,你看到的代码只是传统编程模型的另一个变体。 唯一的新方面是我使用的实际类。 但是,大多数时候,你实际上不会编写很多此代码。 让我们稍微走一些路,了解一种新的编程语言,使你能够以更紧凑的方式编写相同的代码,至少对我来说,更可理解的方式。
可扩展应用程序标记语言 (XAML)
在许多应用程序中,你编写的大部分代码都与创建和更新应用程序的 UI 相关。 事实上,在前面的示例中,除了创建 UI 所需的代码之外,没有其他代码。 在过去几年中,许多开发人员已经学会了使用多种可用标记语言之一来编写应用程序 UI,甚至更愿意定义应用程序的 UI。 “Longhorn”平台定义了一种名为可扩展应用程序标记语言(XAML;发音为“Zamel”的新标记语言,该语言是带有“camel”的韵律)。
使用标记语言定义 UI 比使用过程编程语言具有许多优势。 这些优点包括:
- 更明显的控件层次结构
- 更明显的属性继承
- 通过工具更轻松地处理和解释标记语言
- UI 和过程代码的潜在分离
我喜欢 XAML,我更喜欢使用它来定义 UI,而不是使用本章中介绍的过程类型编码。 但是,不要认为你将能够执行除了 XAML 外的所有内容。
请考虑文档中的此语句:“文档通常完全用 XAML 编写,并在浏览器中显示。我匆忙指出,这句话使用单词 文档,而不是 应用程序,它使用术语 通常限定语句。 编写显示静态内容的文档时,可以在纯 XAML 中创建它。 甚至可以编写一个文档,该文档使用数据绑定来显示和更新数据源中的内容,只使用 XAML。 可以使用 XAML 之外的内容来定义动画和鼠标悬停效果。 除了 XAML,你可以做很多事情。 (事实上,我尽量在 XAML 中执行操作,在代码中尽量少。我的应用程序似乎不太有 bug,工作速度越快,编写的代码就越少!不过,若要编写生产应用程序,通常需要对事件做出反应、提供自定义决策逻辑或包括许多其他非 UI 操作,因此需要混合 XAML 和代码。 幸运的是,这是极其容易做到的。
我将更深入地介绍第 3 章中的 XAML 文件;现在,让我们看看 XAML 的入门:
-
XAML 元素名称是 .NET Framework 类名称。 定义 XAML 元素时,可以有效地创建与 XAML 元素同名的 .NET Framework 类的实例。 - XAML 属性名称 映射到具有相同名称的属性或字段,通常位于类实例中。
在SimpleApplication1.cs程序中,我创建一个窗口,并使用以下代码向其添加一些控件:
// Create the application's main window
mainWindow = new MSAvalon.Windows.Window ();
// Add a dark red, 14 point, "Hello World!" text element
txtElement = new MSAvalon.Windows.Controls.SimpleText ();
txtElement.Text = "Hello World!";
txtElement.Foreground = new
MSAvalon.Windows.Media.SolidColorBrush (Colors.DarkRed);
txtElement.FontSize = new FontSize (14, FontSizeType.Point);
mainWindow.Children.Add (txtElement);
mainWindow.Show ();
以下 XAML 文档生成完全相同的 UI。
HelloWorld.xaml
<Window xmlns="https://schemas.microsoft.com/2003/xaml" Visible="true">
<SimpleText Foreground="DarkRed" FontSize="14">Hello World!</SimpleText>
</Window>
根
XML 分析器将解释与最近、作用域内、默认命名空间属性中指定的命名空间相关的非限定元素名称,xmlns。 指定 xmlns 值为 “https://schemas.microsoft.com/2003/xaml",生成系统将定义元素或其从属元素上的非限定元素名称解释为预定义命名空间集中的类的名称。
让我以更具体的方式重述这一点,以 C# 为例。
using MSAvalon.Windows;
using MSAvalon.Windows.Controls;
using MSAvalon.Windows.Controls.Primitives;
using MSAvalon.Windows.Data;
using MSAvalon.Windows.Documents;
using MSAvalon.Windows.Shapes;
using MSAvalon.Windows.Media;
using MSAvalon.Windows.Media.Animation;
using MSAvalon.Windows.Navigation;
标准默认命名空间声明还会导致生成系统引用 PresentationFramework 和 PresentationCore 程序集,这些程序集包含前面列出的命名空间中的类。
我将 Window 元素的 Visible 属性设置为 true。 这对应于通过调用窗口 Show 方法显示窗口的原始代码。
我在 Window 元素定义中嵌套了 SimpleText 元素。 这会告知系统实例化 MSAvalon.Windows.Controls.SimpleText 对象,使其成为 Window 对象的子对象,并将简单文本对象的值设置为“Hello World!” 字符串。
将上述 XAML 代码保存在名为 HelloWorld.xaml 的文件中,并运行该文件。 浏览器将解释文件中的 XAML 代码并显示 UI,如图 1-1 所示。
图 1-1. 显示 HELLO World XAML 版本的浏览器(单击图片可查看较大图像)
你可能想要使用前面列出的一个默认命名空间中未定义的 .NET 类。 一个典型的示例是使用你创建的程序集中的类。 生成系统需要能够将 XAML 源文件中指定的元素名称映射到正确的程序集中的相应 .NET 类。 XAML 定义名为 的 XML 处理指令 (PI) ?用于进行此关联的映射。
?通过映射 PI,可以定义映射到 CLR 命名空间和程序集的 XML 命名空间前缀。 使用此命名空间前缀限定 XAML 元素名称时,请告知生成系统采用元素名称,将 CLR 前缀添加到名称,并创建具有生成名称的类的实例。 编译器将引用指定的程序集,以便它可以找到类的定义。
以下示例创建 WiseOwl.Statistics.PoissonDeviate 类的实例,该类的定义驻留在 WiseOwl.Statistics.Library 程序集中:
<?Mapping XmlNamespace="stat" ClrNamespace="WiseOwl.Statistics"
Assembly="WiseOwl.Statistics.Library" ?>
<Window xmlns="https://schemas.microsoft.com/2003/xaml" Visible="true">
<SimpleText Foreground="DarkRed" FontSize="14">Hello World!</SimpleText>
<stat:PoissonDeviate Mean="5.0" />
</Window>
我无法强调 XAML 只是生成使用 .NET Framework UI 类的代码的另一种方法。 事实上,你可以使用可视化设计器以图形方式显示 XAML UI 规范的工具。 另一个工具可能会进行反向操作,并允许以图形方式设计 UI,并将其另存为 XAML 文件。 然而,另一个工具可能会将 UI 设计保存为过程代码,这类似于 WinForms 设计器的工作方式。 所有这些方法只是指定相同信息的不同方法。
在本章的前面,我提到浏览器可以在其窗口中呈现 XAML 文件。 仅当 XAML 文件只包含标记,如刚刚显示的简单示例时,浏览器才能执行此操作。 随着 UI 变得更加复杂,除了描述 UI 的 XAML 之外,通常还需要使用事件处理程序和其他非标记源代码。 每当拥有混合源代码库(即标记和非标记源代码)时,都必须使用 MSBuild 实用工具编译标记和源代码。 编译后,可以将应用程序作为独立组件运行,或者让浏览器显示生成的 UI。
总结
好吧! 现在,你已了解新应用程序模型的基础知识。 你已了解如何使用标记以声明方式创建 UI,尽管 UI 非常简单。 可以使用 XAML 文件编写网页的等效内容,并将这些文件部署到服务器供用户浏览。 但是,更有趣的方案通常需要在部署应用程序之前编译应用程序。 因此,让我们直接进入并了解如何生成和部署“Longhorn”应用程序。
© 2003 Microsoft公司。 保留所有权利。
IntelliSense、Microsoft、MSDN、MS-DOS、Visual Basic .NET 和 Visual Studio .NET 是美国和/或其他国家/地区Microsoft公司的注册商标或商标。 此处提到的其他产品和公司名称可能是各自所有者的商标。