首页 > 代码库 > 第八章 用户界面(二)

第八章 用户界面(二)

第八章 用户界面(二)


在 WinForm 上使用控件

 

控件就是类,派生自 System.Windows.Forms.Control,由此类派生出的任何类都能显示在窗体上,只要将它添加到窗体对象的 Controls 集合中。

现在我们看一下用控件画树形的方法。WinForms 库定义了 TreeView 类,这是专门用于显示树形结构的;自然,我们就用这个控件来显示树。使用 TreeView,需要创建它的实例,并设置属性、调用方法,对它进行配置。最重要的,是将需要显示的结点添加到 Nodes 集合中。这个控件准备好以后,就可以将它添加到窗体的 Controls 集合。

TreeView 类用 TreeNode 对象表示结点,因此,我们定义函数 mapTreeToTreeNode,递归遍历树形结构,创建 TreeNode 图形。清单 8-2 中的程序产生图 8-3 的树。

 

清单 8-2 用控件 TreeView 画树

 

openSystem.Windows.Forms

 

//The tree type

type ‘a Tree =

|Node of ‘a Tree * ‘a Tree

|Leaf of ‘a

 

//The definition of the tree

let tree =

  Node(

    Node(

      Leaf "one",

      Node(Leaf "two", Leaf"three")),

    Node(

      Node(Leaf "four", Leaf"five"),

      Leaf "six"))

 

// Afunction to transform our tree into a tree of controls

let mapTreeToTreeNode t=

  let rec mapTreeToTreeNodeInner t (node :TreeNode) =

    match t with

    | Node (l, r) ->

        let newNode = new TreeNode("Node")

        node.Nodes.Add(newNode) |> ignore

        mapTreeToTreeNodeInner l newNode

        mapTreeToTreeNodeInner r newNode

    | Leaf x ->

        node.Nodes.Add(new TreeNode(sprintf "%A" x)) |> ignore

  let root = new TreeNode("Root")

  mapTreeToTreeNodeInner t root

  root

 

//create the form object

let form =

  let temp = new Form()

  let treeView = new TreeView(Dock = DockStyle.Fill)

  treeView.Nodes.Add(mapTreeToTreeNode tree)|> ignore

  treeView.ExpandAll()

  temp.Controls.Add(treeView)

  temp

 

Application.Run(form)

//form.Show()

 

图 8-3. 用 TreeView 控件显示树

 

这段代码大约只有清单 8-1 (自己画树)的一半,还有更多的功能,因为,它可以折叠树中你不感兴趣的部分,这极大地改进了以可管理的方式显示树的大小。

在这个例子中,使用“停靠(Dock)风格”控制控件的外观。即,设置控件的 Dock 属性为一个 DockStyle 枚举值。停靠的控件能更可能占用窗体上的可用空间,如果使用 DockStyle.Left 属性,控件就停在左边;如果使用DockStyle.Right,则停在右边;DockStyle.Top;则停在顶部;DockStyle.Bottom,则停在底部;DockStyle.Fill,则充填整个窗体。如果只有几个控件时,这非常好,因为它有很好的动态效果,当用户调整大小的窗体时,控件的大小也将调整。然而,当有大量控件时会有问题,因为很难用这种方法将大量的控件完美地组合在一起。例如,如果有两个控件都停在左边,就很难确定到底哪一个停靠在最左边,应该占用左边多大的地方。当有大量控件时,更好的方法是要明确地用 Top 和 Left 属性控制其布局。用 Anchor 属性可以创建动态效果,把控件锚定(anchor)在窗体的边缘。下面的例子创建了一个有文本框的窗体,文本框的大小会随着窗体大小的改变而改变:

 

open System

openSystem.Windows.Forms

 

let form =

  // create a form

  let temp = new Form()

  // create a text box and set its anchors

  let textBox = new TextBox(Top=8, Left=8, Multiline=true,

                            Width=temp.Width -30, Height=temp.Height-52,

                            Anchor = (AnchorStyles.Left |||

                                      AnchorStyles.Right |||

                                      AnchorStyles.Top |||

                                      AnchorStyles.Bottom))

 

  // add the text box to the form and return the form

  temp.Controls.Add(textBox)

  temp

 

[<STAThread>]

do Application.Run(form)

//form.Show()

 

[

与原文略有改变,现在文本框为多行模式。

]

 

然而,这种方法使用控件并不总是令人满意的。这里是只显示了一个控件,而通常在一个窗体上,会有十多个控件,甚至上百个。如果要写出所有的控件创建、配置代码,既单调,也容易出错。为了解决这种问题,Visual Studio 提供了窗体设计器,可以可视化地创建窗体。

然而,到现在这止,还没有针对 F# 的设计器,因此,下一节我们讨论F# 如何使用 C# 设计器创建的窗体。

对于 WinForm 的程序员,使用控件的一个困难在于,如何从众多控件中进行选择。在这一章中,我们只讨论了一个控件。然而,说到学习,没有什么可以取代经验。MSDN 库(http://msdn.microsoft.com)提供了一个很好的参考,但是,它的信息量对于这些新主题也很难让人满意。因此,我把一些最有用的部分进行了汇总,列在表 8-3 中,有助于使用学习曲线变得平坦一些。

 

表 8-3 WinForm 常用控件及用法

控件

描述

Label

显示文本信息。

通常,大多数其他控制应附带 Label,以说明其用途。在 Label 的 Text 属性的文本中加 &,会使其后的一个字母有下划线,通过按键可以跳到与此 Label 相关(即 tab 序号的下一个)的控件,方法是按Alt+<字母>。这极大地提高了应用程序的可用性。

TextBox

用于输入文本的框。

默认情况下文本框是单行,如果将 Multiline 属性设置为 true,可以支持多行;根据自己的喜好,也可以选择 WordWrap 和 ScrollBar 属性;如果想让文本框中显示的文本可以复制、粘贴,可以通过设置 ReadOnly 属性实现。

MaskedTextBox

这个控件与文本框有许多相似之处。

通过设置 Mask 属性,可以限制用户输入的数据。

Button

按钮控件,用户可以单击。

像 Label 控件一样,在按钮的 Text 属性的文本中加 &,使其后的一个字母有下划线,通过按键可以跳到此按钮,方法是按 Alt+<字母>。这极大地提高了应用程序的可用性。

LinkLabel

这个控件的名字有点误导,它不像标签,而更像按钮,看起来像 HTML 链接。这个控件非常适合于网站环境,当单击这个按钮,打开页面。

CheckBox

选择框控件。用于选择一组不互斥的选择项。

RadioButton

与 选择框控件相似,但选择项是互斥的。

放在同一个容器中的选择项自动互斥。容器通常是窗体。

DateTimePicker

从下拉的日历中选取日期。

MonthCalander

月历。

ComboBox

组合框,用户可以从下拉列表中选择。通过数据绑定显示动态数据集(在第九章更细讨论)。

ListBox

列表框,与组合框相似,只是列表项显示在窗体上,而不是在下拉列表中。如果窗体上有大量的空间可以用这个控件。

DataGridView

数据网格视图,虽然可以显示任何表格数据,但是更适宜显示数据库表。应该用这个控件代替以前的 DataGrid(到第九章会进一步讨论)。

TreeView

树视图,这是另一个适合显示动态数据的控件,最适合显示树形数据。

ProgressBar

进度条,对于长时间运行的任务,给用户以反馈是极其重要的。

RichTextBox

显示和编辑富文本,比标准的文本框有更多的格式。

WebBrowser

显示 HTML 文档,因为很多信息是以 HTML 格式提供的。

Panel

把窗体分成不同的部分,配合 HScrollBar 和 VscrollBar 更有效。

HScrollBar

水平滚动条,使 Form 或 Panel 容纳更多的信息

VScrollBar

垂直滚动条,使 Form 或 Panel 容纳更多的信息

TabControl

带选项卡的用户控件