本文基于 Microsoft Visual Studio 2005(以前的代号为“Whidbey”)的预发布版本。这里包含的所有信息都有可能发生更改。

本文讨论: 

• Windows 窗体控件的新增功能 
• 使用主题 
• 绑定和显示数据 
• 其他特定于数据的功能

.NET 框架 1.0 确实让 Microsoft 找到了一个很理想的平台。.NET 不仅意味着一种开发人员生成和分发基于 Windows® 的应用程序方式的根本转变,而且它还为向上和向外扩展功能创建了非常优秀的技术平台。在这一点上,Visual Studio® 2005 就是一个明证,通过提供新功能和改进的功能,它在这两方面都做得非常好。这些改进的内容主要明确涵盖了 Microsoft®.NET 框架的 Windows 窗体子集,从核心 System.Windows.Forms 开始,辐射到了多种支持技术,这些技术有新有旧,其中包括 ADO.NET、ObjectSpaces 和 ClickOnce 部署。

在 Visual Studio 2005 中,随处可见对生产效率的改进。它们包括 IDE 增强功能、改进的控件和数据设计器,以及代码生成。习惯于编写大量代码的人可能对只需要为多种方案编写如此少的代码感到沮丧,而我们其余的人则将更多时间放在了重新运行 Battlestar Galactica。

System.Windows.Forms

大量工作已经聚焦到 System.Windows.Forms,它是 Windows 窗体的核心技术。到撰写本文时为止,命名空间的可用表面区域(由公共类型和成员组成)已经分别增加了 67% 和 127%,这说明 Visual Studio 2005 肯定是一个重要版本。虽然本文没有用足够长的篇幅来讨论所有内容,但图 1 概述了主要的新改进区域,并展示了涉及许多区域的新增功能和增强功能,例如,更好的主题支持、改进的数据绑定,以及 GridView 控件。

Windows 主题支持

虽然创建新的 Windows 窗体项目的过程仍然和过去一样,但您可以从结果中发现一项更改:对 Windows 主题的默认支持。Windows 主题是用于整个系统外壳的用户设置,用于指示 Windows UI 的外观。可以通过右键单击桌面,然后在“显示属性”对话框中单击“属性”|“主题”来指定主题。

因为 Windows 主题是用户指定的,所以应该由 Windows 窗体应用程序来反映它们。现有的 .NET 版本中提供对主题的支持,但 .NET 框架的 1.0 版本要求开发人员向文件系统中的特定位置添加特殊命名的清单文件。.NET 框架版本 1.1 通过提供 Application.EnableVisualStyles 方法来启用支持,并且通过在实现该方法的每个控件上将 FlatStyle 属性设置为“System”,从而简化了这一过程。Visual Studio 2005 则通过在默认情况下,在新的 Windows 窗体项目的默认窗体中包含对 EnableVisualStyles 的调用,来进一步改进该过程: 

public class Form1 : System.Windows.Forms.Form { 
 
   •••
   [STAThread]
   static void Main() { 
 
     Application.EnableVisualStyles();
     Application.Run(new Form1());
   }
   •••
  }

在传统做法中,将控件的 FlatStyle 设置为 System 来指示由操作系统决定控件在显示时的外观。现在,当 FlatStyle 被设置为默认值“Standard”时,大多数 Visual Studio 2005 控件将按照目前正在使用的 Windows 主题进行显示。这在语义上等效于 System 设置,因此您无需在设计器中设置它。无论 FlatStyle 是“Standard”还是“System”,对开发人员的益处是主题敏感性,包括在运行时对主题更改的动态响应的支持(无需使用代码)。

控件布局和配置

要支持 Windows 主题,只需创建项目或窗体,并将所需控件拖到上面便可。但是,将控件放在窗体上并对其进行配置是一个很耗时的过程,对复杂的窗体来说尤其如此。为了使该任务更易于完成,Windows 窗体设计器提供了几个用来减少设计时杂务的新功能,包括 Snap-To 对齐、编辑属性模式和智能标记,您可以就在控件上来访问这些功能。

虽然,您仍然可以使用 Visual Studio 布局工具栏来水平和垂直对齐控件,但是,一旦控件在窗体中,就只能使用该方式来调整布局。另外,可以使用 Snap-To 对齐来获得与将控件放在窗体上并拖动它们相同的效果,这样可以避免布局工具栏和关联的设计时支出,包括选择控件和单击工具栏按钮。Snap-To 对齐显示为一条或多条粘滞蓝线,用于指导控件与其他控件以紧密接近的方式对齐。

使用增强的 Windows 窗体支持为 .NET 应用程序设计丰富的用户界面_控件

图 2 编辑属性

另一个新功能是编辑属性模式,它允许您逐一处理控件并直接在属性页上更改它们的属性。要启动编辑属性模式,可以从 Windows 窗体设计器上的任何上下文菜单中选择“Edit Properties Mode”,或者单击相同名称的菜单项。下一个步骤是选择并逐一查看每个属性,并根据需要编辑它们。图 2 显示了该过程。完成编辑后,通过单击“Return to Layout Mode”可以返回到正常编辑状态。设置属性是更改控件的简单方式。用一个更相关的控件来完全替换另一个控件并不一件易事;这需要删除现有控件,并在窗体上放置一个新控件,然后重新配置它。此类复杂的多步设计器任务是使用智能标记的完美体现,这样的任务被打包成单个步骤的设计时任务,并作为相关控件附近的菜单项图标公开。智能标记还公开简单的设计时任务(尽管此类任务执行得很频繁),包括在将文本框放到窗体上时设置它的文本属性。

控件和数据绑定

除了 IDE 改进以外,Visual Studio 2005 中的 Windows 窗体还提供了新控件,并改进了旧有的常用控件(例如,文本框和组合框)。作为某些正在使用的新控件和改进控件的示例,图 3 显示了 UberBrowser,生成该控件所用的代码比在 Windows 窗体的以前版本中所需的少得多。

使用增强的 Windows 窗体支持为 .NET 应用程序设计丰富的用户界面_windows_02

图3 使用了新控件的 Web 浏览器

这个简单的示例演示了 Visual Studio 2005 中的增强工具箱如何允许您用更少的代码生成更多的功能。例如,实现全功能 UberBrowser 的设计大约需要用 10 分钟,并且只需用 85 行代码便可钩挂传统的 Web 导航事件,并实现 URL 导航历史。实际的 Web 导航和 HTML 呈现工作由右侧窗格中的 WebBrowser 控件执行。拆分栏和左右两侧的窗格由单个 SplitContainer 提供。

组合框(如图 3 所示)提供新的 autocompletion 支持。Autocompletion 是通过三个属性实现的,首先是 AutoCompleteMode,它允许您通过同名枚举设置

enum AutoCompleteMode { 
 
   None = 0x0,        // No autocompletion
   AutoSuggest = 0x1, // Possible matches chosen from drop-down list
   AutoAppend = 0x2,  // Possible matches 
                      // appended to text 
                      // while typing 
   AutoSuggestAppend = 0x3 // AutoSuggest and 
                           // AutoAppend combined
 }

“None”以外的选项要求将 AutoCompleteSource 属性设置为已由 AutoCompleteSource 枚举指定的几个系统 autocompletion 源之一: 

enum AutoCompleteSource { 
 
   FileSystem = 0x1,       // File system
   HistoryList = 0x2,      // All URLs from History list
   RecentlyUsedList = 0x4, // All URLs from Recently Used list
   AllURL = 0x6,           // HistoryList + RecentlyUsedList
   AllSystemSources = 0x7, // FileSystem + AllURL
   CustomSource = 0x40,    // AutoCompleteCustomSource
   None = 0x80             // No source
 }

CustomSource 指示组合框:您将从存储在 AutoCompleteCustomSource 属性中的项的集合中提供 autocompletion 选项。目前,只有组合框和文本框能提供 autocompletion。

GridView

工具箱中的大多数控件支持通过本机数据绑定基础结构将数据绑定到任意数据源。在很多方案中,特别是在原型设计和 RAD 开发中,数据绑定是很关键的功能。通过改进类型化的 DataSet、提供包括 GridView 和 DataContainer 在内的新控件,以及为更快的开发工作提供更丰富的设计时支持,Windows 窗体团队已经极大地增加了数据绑定空间。这些功能允许您以同样轻松的手段生成字段样式或列表样式的用户界面。

有时,列表样式的用户界面对呈现和处理绑定的数据是最适合的,因此,Microsoft 在以前版本的 .NET 框架中都包括了 DataGrid 控件。对于 Visual Studio 2005,Windows 窗体团队响应了针对 DataGrid 的来自社区的反馈,并决定构造一个新的网格控件 — System.Windows.Forms.GridView(请参阅图 4)。

DataGrid 和 GridView 之间的最显著差别可能是 GridView 对象模型,该模型已被抽象为建立在列、行和单元格之上的自然的网格结构,这些元素允许开发人员通过大量可以直观找到的功能逻辑地进行数据钻取,这些功能包括: 

• 通过样式、格式、布局和项选择提供的丰富的用户界面自定义支持。 
• 较之 DataGrid 允许的种类,通过一组更丰富的列类型(包括图像)能提供更广泛的用于本地显示的数据。 
• 例如冻结列(与 Microsoft Excel 中类似)和运行时列重新排序(与 Microsoft Outlook® 中类似)这样的极佳功能。 
• 提供了 100 多个事件,使您能够更细致地控制导航、编辑、验证、自定义绘制和错误处理。

通过与全面的设计时体验进行组合,该丰富的功能集支持在较少依靠代码(在某些情况下,由于将常见的 DataGrid 编码方案转成本机 GridView 方法、属性和事件)的情况下进行快速自定义操作。此功能的一个示例是通过单击单元格来选择行,行选择功能现在由 GridView 作为 SelectionMode 属性公开。当然,一个控件不可能适用于每个人。当控件不符合要求时,开发人员可以依靠可扩展性来合并自定义功能。GridView 基础结构提供了可以从中派生和插接的多种单元格、行和列基实现。总的来说,GridView 将是一个比 DataGrid 好得多的网格样式控件。

类型化 DataSet

GridView 控件是可以绑定到数据源(例如,数组、集合和类型化 DataSet)的一系列控件的一部分。类型化 DataSet 的优点是,.NET 框架探测操作允许将控件绑定到设计器中,以帮助开发人员在设计时实现用户界面可视化。GridView 通过在设计时为数据源的每个字段自动生成列来支持该功能。Visual Studio 2005 增强了类型化 DataSet,从而使操作更简单。您在设计器中花费的时间将更少,这是由于现在类型化 DataSet 能够完全解密数据源元数据,包括外键约束以及自动增量种子和步骤,如图 5 所示。

使用增强的 Windows 窗体支持为 .NET 应用程序设计丰富的用户界面_ui_03

图 5 默认的类型化 DataSet

该设计器还会生成 Fill 查询,该查询会将表的 SELECT 语句包装起来,并在类型化 DataSet 上作为同名方法实现。一些情况下,初始指定的 SELECT、INSERT、UPDATE 和 DELETE 语句并不能在所有情况下使用。例如,尽管有时您可能只需要返回单个雇员,但 Full 方法将返回所有雇员。在这种特殊情况中,使用相同的表并用更具体的查询来填充它将是有用的。类型化 DataSet 设计器允许您通过在表的上下文菜单中选择“Add”|“Query”,来从适当的表的上下文菜单添加您自己的查询,因此适合在这种情况下使用。

打开“DbTable Query Wizard”对话框可以帮助您构造查询,然后将以新的数据更新表。完成对类型化 DataSet 的配置后,通常将它绑定到用户界面中的一个或多个控件。在 Visual Studio 2005 中,类型化 DataSet 可以直接绑定到实现了 DataSource 和 DataMember 属性的控件,无需向窗体添加 DataSet。

DefaultInstance

经常使用类型化 DataSet 的人都知道,通常将每个新的类型化 DataSet 类用在应用程序的一个地方。因为 Windows 窗体团队知道这一点,并且想让操作更容易,所以他们已经将称为 DefaultInstance 的静态属性放到每个生成的类型化 DataSet 类中,使其包含该单个实例。它的实现方式如下所示:

public static EmployeeTDS DefaultInstance { 
 
      get { 
 
        if (_defaultInstance == null) { 
 
          _defaultInstance = new Northwind();
        }
        return _defaultInstance;
      }
    }

DefaultInstance 属性的使用方式如下所示: 

public class Form1 : System.Windows.Forms.Form { 
 
   •••
   private void Form1_Load(
     object sender, System.EventArgs e) { 
 
     // Load data
     EmployeeTDS.DefaultInstance.LoadData();
   }
   •••
 }

Databound 控件使用默认实例的类型名称(默认情况下是 ProjectNamespace.TypedDataSetName)来设置它们的 DataSource 属性,但随后的用于指定 DataMember 的过程保持不变。

DataContainer控件

GridView 控件是复杂的绑定控件的示例,这意味着它知道如何管理数据绑定,以支持导航、插入、更新和删除。另一方面,简单的绑定控件并不知道这一点,因此需要您通过数据源的绑定管理器(通常使用 VCR 样式的用户界面)实现等效的支持。当您想将列表样式的数据作为一组字段而不是网格提供时,要使用简单的绑定控件。该方式要求您手动将字段作为一组适当的控件(例如,标签和文本框)添加到窗体,其结果如图 6 所示。

使用增强的 Windows 窗体支持为 .NET 应用程序设计丰富的用户界面_.net_04

图 6 基本用户界面

虽然可以手动实现这样的 Details Form,但是在 Visual Studio 2005 中,可以使用绑定到类型化 DataSet 的 DataContainer 很方便地实现它们。只需从 DataContainer 的智能标记中选择 Details Form 菜单项。

该功能将从所选的数据源自动生成所有字段。此外,在默认情况下,DataContainer 将加载和保存数据,并添加 VCR 样式的导航和编辑功能,无需您编写代码。其结果如图 7 所示。

使用增强的 Windows 窗体支持为 .NET 应用程序设计丰富的用户界面_windows_05

图 7 使用 VCR 控件的字段样式的用户界面

如果用户界面要求发生更改,而且表格样式的用户界面更合适,则可以通过从 DataContainer 的智能标记选择适当的选项,使用 DataContainer 来完成困难的用户界面更改工作。设计器将删除全部现有的控件,并将它们替换为单个 DataGrid(尽管在 Visual Studio 的未来版本中很可能替换为 GridView)。

主-从信息绑定

多功能的 DataContainer 恰好也是构造主-从 (master-detail) 信息用户界面的好工具,主-从信息用户界面为关系数据库中使用的一对多关系提供了基于窗体的可视化表示形式。该用户界面的一个示例是 Employees-Orders 关系,只需将 Orders 表添加到类型化数据中即可正确配置该关系。

使用增强的 Windows 窗体支持为 .NET 应用程序设计丰富的用户界面_windows_06

图 8 主-从信息窗体

因为我们已经生成了主用户界面(如图 7 所示),所以,我们只需将 GridView 拖到窗体上,并将它的 DataSource 设置为 DataContainer,然后将它的 DataMember 属性设置为 Orders-OrderDetails 关系(在本例中是 FK_Orders_Employees)便可,其结果如 图 8 所示。

ClickOnce部署

当您最终拥有了窗体需要的所有控件,以及用于使控件共同工作的代码时,您便可以着手进行应用程序部署了。将一个企业级的 Windows 窗体应用程序部署到任何规模不确定的用户群,是对安装和版本控制的一大挑战,因此以前的开发人员非常喜欢使用具有丰富的 Windows 用户界面的 Web 应用程序,以便获得由此而带来的部署好处。

.NET 出现之后,Microsoft 开始创建一个基础结构,以便使部署 Windows 窗体应用程序与部署 ASP.NET 应用程序一样容易。在 Visual Studio 2005 之前,.NET 框架支持无接触部署,这种部署允许 Windows 窗体应用程序从 URL 或通用命名约定 (UNC) 文件路径进行部署,并在由客户端机器上的代码访问安全性 (CAS) 控制沙盒之中执行。在 Visual Studio 2005 中,无接触部署已经进化为 ClickOnce 部署,这种部署方式将几个新功能合并在一起,为 Windows 窗体开发人员提供了与 Web 应用程序一样平滑的部署基础结构。尤其是,ClickOnce 为包括在 Visual Studio 结构中的所有功能提供了改进的支持,这些功能包括应用程序交付、版本控制和回滚、更好地控制客户端应用程序安装、权限提升和设计时配置支持。

配置 ClickOnce 部署

在设计时,可以通过 Visual Studio 2005,在项目的“Configuration Properties”中的“Publish”属性页中配置 ClickOnce 部署。不同的部署源(文件服务器、Web 服务器或 FTP 服务器)在不同的方案中具有的意义取决于基础结构和用户群。[编者更新 — 2004 年 7 月 1 日:FTP 服务器可以作为发布目标使用,但它们不能作为部署源使用(也就是说,客户端无法从 FTP 服务器执行安装)] ClickOnce 部署允许您指定应用程序将发布到哪些部署源,并从哪些部署源执行安装,以及安装时采用的机制(例如,通过 Web 页)。还可以通过配置应用程序是否物理地安装到客户端机器来控制安装。如果安装到客户端,则可以规定应用程序是否要在加载或运行之前检查更新、检查的频繁,并强制执行所需的更新(这是部署关键更新的有用选项)。还可能指定应用程序先决条件,最可能的先决条件是 .NET 框架本身。还可以从 Security 属性页设置几项安全设置。

开始发布时,您可以通过单击“Project”|“Publish Project”(用于生成并发布应用程序)这一步骤完成应用程序的生成和发布。发布过程由发布向导进行管理,该向导基本上会再次访问您的发布配置设置,这就允许您在每次发布时更改这些设置。发布过程中的最后一个窗体将显示一个列表,供您确认自己的设置,而且该列表还提供了一个选项,供您选择是发布应用程序还是返回并更改设置。然后,发布向导将接受您的选择,并根据需要发布应用程序。

部署

当用户导航到部署 Web 页,并单击先决条件和/或应用程序的相应超级链接时,将开始进行部署。应用程序链接指向一个 .deploy 文件,而不是应用程序可执行文件本身。.deploy 文件是 ClickOnce 部署所需的两个清单之一,它指定了应用程序部署和更新要求。两个文件中的第二个是 .manifest,它指定了要执行的应用程序所需的文件。这是等效于程序集清单的语义。.deploy 和 .manifest 文件都是在客户端机器上由 ClickOnce 部署服务 System.DeploymentFramework.Service.exe 进行处理。该服务与 .NET 框架一起安装,并在 .deploy 文件首次被请求时启动。虽然用户看不见任何这样的后台活动,但可以看到一个用于确认下载的对话框。[编者更新 — 2004 年 7 月 1 日:如果联机应用程序运行在沙盒中,那么用户可能看不到该对话框。]下载完成后,实际的应用程序将加载到 AppHost.exe 中,并从它开始执行。应用程序存储在本地缓存中,除非您指定不执行客户端安装。[编者更新 — 2004 年 7 月 1 日:应用程序总是缓存在本地。]虽然随后的应用程序调用将总是需要 .deploy,但是该应用程序将从本地缓存执行,直到 .deploy 指定新的版本在服务器上可用。

如果应用程序的安全要求高于那些为应用程序执行时所在的区域(例如,Internet 或 Intranet)配置的安全要求,那么,ClickOnce 将向用户提供将应用程序权限提高到所需级别的机会,从而确保应用程序能够正确执行。否则,应用程序将永远不会启动,因为它根本没有运行机会。[编者更新 — 2004 年 7 月 1 日:如果应用程序未被授予所需权限,则不会被下载。]

ClickOnce 版本控制和回滚

如果应用程序被请求,系统将向“开始”菜单中添加一个图标,并将一个条目添加到“控制面板”|“添加或删除程序”中。在“添加或删除程序”中,可以完整地卸载应用程序或恢复以前的版本(如果有)。ClickOnce 版本控制依赖于您使用 AssemblyVersionAttribute 为应用程序指定的版本号,在默认情况下,AssemblyVersionAttribute 会自动生成到每个 Windows 窗体项目的 AssemblyInfo.cs 文件中。它的内容如下所示:

[assembly: AssemblyVersion("1.0.*")]

版本号用于确定新版本何时可供下载。它还用来命名应用程序所驻留的部署文件夹和客户端缓存文件夹。这两个文件夹的命名约定是 ApplicationName_major#.minor#.build#.revision#。

ClickOnce 部署是一项功能强大的技术,它还提供了其他许多好处,由于篇幅所限,本文无法对它们进行描述。但是,使用 ClickOnce 的主要动机是使 Windows 窗体应用程序的部署、安装和版本控制更加容易。有关 ClickOnce 的更多信息,请参阅这一期 MSDN ® Magazine 中由 Brian Noyes 撰写的文章“ClickOnce: Deploy and Update Your Smart Client Projects Using a Central Server”。

小结

当您考虑到 Visual Studio 2005 中为数众多的新功能时,会发现我们只是刚刚开始讨论您有可能在 Windows 窗体开发中会使用到的众多技术。这些技术包括 ADO.NET 中的改进,以及使用全新的 ObjectSpaces 通过对象-关系映射实现的对全新的关系数据访问方式的支持。在这里,我们已经初步介绍了最重要的新功能,并解释了它们所带来的生产效率的相应提高,我们首先介绍了 Visual Studio 中的 IDE 和设计器改进,然后介绍了在以前版本基础上改进的控件(像文本框和组合框),或全新的控件(像 GridView 和 WinBar)。GridView 和 DataContainer 控件在结合类型化 DataSet 增强功能的情况下,将帮助您把更丰富的数据表示形式和处理方式更快地运用到应用程序中。

最后,ClickOnce 部署简化了整个 Windows 窗体部署过程,同时还提供了可与传统安装程序相媲美的部署功能。

Michael Weinhardt 目前正在协助修订 Chris Sells 的书 Windows Forms Programming in C#,同时为 MSDN Online 名为“Wonders of Windows Forms”的每月专栏撰写文章。有关进一步的信息,请访问 http://www.mikedub.net

Chris Sells 是 MSDN Online 的内容策划人员,他目前的主要精力全部放在了 Windows 下一个版本 —“Longhorn”(http://msdn.microsoft.com/longhorn) 上面。要了解 Chris 以及有关他的各种项目的信息,请访问 http://www.sellsbrothers.com。