介绍
由当前关于互联网的许多讨论来看似乎微软的Visual Studio开发系统已经完全不再支持开发传统的基于Windows操作系统的应用程序了而实际情况是微软依然非常重视对基于Windows的应用程序的开发
Win Forms是一种全新的窗体形式开发人员可以利用它创建充分利用微软的Windows操作系统中丰富的用户接口的应用程序Win Forms是微软的NET平台的一部分采用了许多新的技术包括一个公共应用程序框架可管理的执行环境集成的安全性和面向对象的设计原则此外Win Forms还提供了对方便迅速连接到互联网服务和创建基于ADO+数据模型的应用程序的支持有了Visual Studio中全新的共享开发环境开发人员就能够使用包括Visual Basic和C#在内的任何支持NET平台的编程语言开发基于Win Forms的应用程序
Win Forms是什么?
就象在上面提到的那样Win Forms是NET Framework中专指Windows客户端UI编程的名字空间它与被称作Web Forms的ASP+ UI的设计原理相同但其中的类和具体的实现是完全不同的Win API和Web组件之间的类是不能够互相转换的然而象NET框架中的其他部分一样一致性是其最优先考虑的部分目的是让一个Win Forms开发人员能够迅速地适应Web Forms的编程方式反之亦然例如二个名字空间都有Button类其中都有文本域OnClick事件和ForeColorBackColorFont等属性
Win Forms控制是完全基于SystemWinFormsControl类的Control类有基本的HWND功能处理大部分常见的WM_xxxx消息从Control类派生出的是RichControl控制它添加了输出逻辑和绘制代码SystemWinForms名字空间中的大部分控制都是由继承RichControl得来的ScrollableControl添加了对窗口用户区滚动的支持一般情况下滚动支持是通过ContainerControl控制获得的ContainerControl控制是由继承
ScrollableControl控制而得来的其中添加了对子控制焦点和标签进行管理的支持由继承ContainerControl而生成的是Form它是Win Form的最高层的控制它有控制标题条系统菜单不规则窗口和缺省控制的属性另一个由继承ContainterControl而生成的是UserControl它就是开发人员可以创建的控制的基本类UserControl是用来管理其他子控制的微软的Visual Studio NET中有可视化的UserControl和Form设计器我们可以发现用来添加和设计由继承它们生成的类的工程条目
我们已经讨论了有关Win Forms的最基本的知识下面我们就来讨论Win Forms的一些深层次的特性
较短的学习周期
Win Forms的首要目的是能够尽可能地提高开发人员在开发Win平台应用程序的编程效率无论是GDI还是窗口状态管理在Win中编程者相当困难的例如象WS_BORDER或WS_CAPTION等窗口风格只能在创建窗口时设定或修改当然了象WS_VISIBLE或WS_CHILD等窗口风格可以在已经创建的窗口上进行修改Win Forms就能够消除这种不统一性确保操作可以在所有时间以同一种方式进行可以在任何时候以任何顺序修改Win Forms控制的属性并产生希望的效果在改变这些属性时需要创建新的HWNDWin Forms会自动地创建窗口并对它进行合理的设置
使用Win Forms获得控制的通知或事件也更加简单所有的Win Forms事件都是基于一种被称作Delegates的通用语言运行库功能的Delegates是一种安全函数的指针可以为任何控制的任何事件添加Delegate事件自理程序我们也无需通过重载创建一个处理所有事件的类创建一个事件图或者为一个类中的所有事件实现一个接口而只会执行其中的一个事件也可以通过重载继承类进行处理但一般情况下只有控制的创建者和在高级的应用程序设计中才会这样作接收一个按钮的Click事件是相当简单的
public class ButtonClickForm: SystemWinFormsForm {
private SystemWinFormsButton button;
public ButtonClickForm() {
// 创建按钮
button = new SystemWinFormsButton()
// 添加事件处理程序
buttonAddOnClick(new SystemEventHandler(button_Click))
// 在窗体上添加按钮
thisControlsAdd(button)
}
private void button_Click(object sender EventArgs e) {
MessageBoxShow(button clicked!)
}
}
在上面的代码中我们已经创建了一个按钮并添加了一个事件处理程序方法button_Click当该按钮被点击时其中的几行代码就会开始执行
着手开发Win Forms工程也是相当简单的在Visual Studio NET中创建Win Forms工程只会生成一个被编译的文件Formcs而不会生成头文件接口定义文件引导应用程序文件资源文件和库文件工程所需要的所有信息都包含在窗体的代码中其结果是工程可以很方便地由一个单一窗体组成的应用被扩充为包括有多个代码文件复杂的由多窗体构成的应用程序其中没有需要连接的临时对象文件只有代码文件和已经建立的DLL文件随着慢慢熟悉这种方法创建NET框架应用程序和C/C++应用程序在复杂性方面的判别就会越来越明显由于信息只包含在代码文件中在Visual Studio NET环境之外创建工程也是相当简单的而无论是Visual Basic代码C#代码或是其他任何支持NET框架的语言写成的
由于Win Forms是建立在通用语言运行库的因此开发人员可以选择任何一种支持通用语言运行库的编程语言开发Win应用程序开发人员可以使用从C#到COBOLEiffelPerl在内的种编程语言开发Win Forms应用程序(或者Web Forms应用程序和Data应用程序)这使得掌握多种编程语言的开发人员可以高效地使用Win Forms建立应用程序
输出布局
如果你曾经尝试着创建一个能够正确地改变大小的窗体就会发现这是多么困难了/MFC和以前的Visual Basic没有对此提供任何内置的支持但在Visual Studio NET中仅仅需要几行的代码(甚至这些代码不需要你动手编写因为在设计窗体时的Property Browser(属性浏览器)中就能实现这样的功能)就能创建一个能够正确地改变大小的对话框
基本的输出布局是由二部分组成的Anchoring和DockingRichControl类有一个Anchor属性这是一个枚举型变量的值通过或运算来描述一个控制与其父控制边缘的距离例如如果在一个窗体上创建了一个按钮并且将其Anchor属性设置为AnchorStylesBottomRight则在改变大小时按钮将与窗体的下右边缘保持相同的距离如果将Anchor属性设置为AnchorStylesAll按钮将与窗体的四周保持固定的距离按钮就会改变自己的大小来符合这一要求
Docking是Anchoring的一种特殊情况RichControl的Dock属性定义控制与父控制的哪个边相接触它的值可以是TopLeftRightBottom或Fill当父控制的大小变化时它将仍然维持与特定边缘的距离将一个控制移动到移动到父控制的底部并将Anchor设置为AnchorStyleBottomLeftRight等同于将Dock属性设置为Bottom在本例中列表框与窗体的左边缘相接触按钮与窗体的顶左和右边保持一定的距离因此它们能够维持相对的位置和大小下面例子中对话框(图)是使用Visual Studio NET中的Win Forms Designer设计的在创建它时我用了分钟的时间而没有编写一行代码
// ResizableSamplecs
namespace ResizableSampleNamespace {
using System;
using SystemDrawing;
using SystemComponentModel;
using SystemWinForms;
///
/// Summary description for ResizableSample
///
public class ResizableSample : SystemWinFormsForm {
///
/// Required by the Win Forms designer
///
private SystemComponentModelContainer components;
private SystemWinFormsButton button;
private SystemWinFormsButton button;
private SystemWinFormsButton button;
private SystemWinFormsListBox listBox;
public ResizableSample() {
// Win Form Designer要求下面的初始化函数
InitializeComponent()
}
///
/// 清除所使用的资源文件
///
public override void Dispose() {
baseDispose()
componentsDispose()
}
///
/// 应用程序的主入口
///
public static void Main(string[] args) {
ApplicationRun(new ResizableSample())
}
///
/// Designer所需要的方法不要使用编辑器编辑其中的内容
///
private void InitializeComponent()
{
ponents = new SystemComponentModelContainer()
thisbutton = new SystemWinFormsButton()
thisbutton = new SystemWinFormsButton()
thisbutton = new SystemWinFormsButton()
thislistBox = new SystemWinFormsListBox()
//@design thisTrayLargeIcon = false;
//@design thisTrayHeight = ;
thisText = Resizable Dialog;
thisIMEMode = SystemWinFormsIMEModeOff;
thisAutoScaleBaseSize = new SystemDrawingSize( )
thisClientSize = new SystemDrawingSize( )
buttonLocation = new SystemDrawingPoint( )
buttonSize = new SystemDrawingSize( )
buttonTabIndex = ;
buttonAnchor = SystemWinFormsAnchorStylesTopLeftRight;
buttonText = Cancel;
buttonLocation = new SystemDrawingPoint( )
buttonSize = new SystemDrawingSize( )
buttonTabIndex = ;
buttonAnchor = SystemWinFormsAnchorStylesAll;
buttonText = Filler;
buttonLocation = new SystemDrawingPoint( )
buttonSize = new SystemDrawingSize( )
buttonTabIndex = ;
buttonAnchor = SystemWinFormsAnchorStylesTopLeftRight;
buttonText = OK;
listBoxSize = new SystemDrawingSize( )
listBoxDock = SystemWinFormsDockStyleLeft;
listBoxTabIndex = ;
listBoxItemsAll = new object[] {Item OneItem TwoItem ThreeItem Four};
thisControlsAdd(button)
thisControlsAdd(button)
thisControlsAdd(button)
thisControlsAdd(listBox)
}
}
}