副标题#e#
摘要:本文接头了如何利用 Visual C++ .NET 的托管扩展针对 Windows 窗体编程,并提供了利用直接会见 Windows 窗体类的手动编程技能的示例,以及利用 Windows 窗体设计器的示例。另外,本文还对 Windows 窗体和 Microsoft 基本类 (MFC) 应用措施举办了较量。
简介
恒久以来,措施员们都利用 C 和 C++ 来开拓 Windows GUI 应用措施。对付我们傍边许多人来说,这一段汗青可以追溯到 Windows 2.0 时期,当时,我们利用基于 C 的 16 位 Windows API,即便只是显示一个窗口,也需要编写数十行代码。幸运的是,跟着时间的推移,抽象的级别越来越高,越来越好。在 1992 年,Microsoft 刊行了 Programmer’s Workbench,个中包罗 Microsoft 基本类库 1.0 版。Microsoft 基本类库 1.0 版包括约莫 60 个类,用于包装窗口化编程和绘制部门的 16 位 Windows API。到 2002 年为止,Microsoft 基本类库 7.0 版已经成长为高出 200 个类,而且,其用途已经扩展为可以或许提供 Microsoft Win32 API 的完整 C++ 工具模子替代物。
固然 MFC 很是强大,但它也有许多缺点,好比它只是 Win32 API 外的一层薄薄的面板,而且对付许多措施员来说,它过分巨大,很难有效地利用。凡是,要开拓 Windows 应用措施,仍需要直接会见 Win32 API,出格是在对 Windows 应用措施所需的根基成果的要求不绝晋升的环境下。因此,要开拓任何成果然正强大的 Windows GUI 应用措施,需要淹灭大量时间精神。为了应对应用措施开举事度不绝提高的状况,Microsoft 于 2002 年头刊行了一个针对 Windows 平台的新编程情况。该情况称为 .NET 框架,它为开拓人员提供了一个托管 应用措施运行库,以及称为 .NET 框架类库的大量库。.NET 框架可以打点内存和安详性,从而可以或许发生更为靠得住的应用措施。.NET 框架类库提供了一个大型、资源富厚和统一的类库,任何 .NET 语言(包罗 Micrisoft 为 .NET 措施员提供的 C++ 的托管扩展和 C++ 的托管版),都可以以沟通的方法同等地会见该类库。作为 .NET 框架的一部门,Windows 窗体是一组用于构建客户端 Windows GUI 应用措施的类。
本文中,我们将深入相识如何利用 C++ 的托管扩展编写 Windows 窗体代码,先先容如何从新开始编写,然后讲授如何利用 Microsoft Visual Studio .NET 2003 来完成这一任务。与此同时,我们将着重先容 Windows 窗体的一些常用成果,如自念头关和数据绑定。最后,我们将把留意力会合到 Windows 窗体与 MFC 的较量以及在进一步利用托管扩展时,如何殽杂利用这两套东西。
什么是 Windows 窗体?
Windows 窗体是一个窗口化东西包,而不像 MFC 一样是完整的应用措施框架。事实上,相对付 Windows 窗体所提供的用于构建基于文档的独立应用措施的成果来说,MFC 提供的成果更多。譬喻,假如要生成一个文本编辑器,在 MFC 中,只需运行一个领导,选择适当的选项并编写若干行代码即可完成。仅仅是通过运行该领导获得的应用措施就包括了一个状态栏、一个东西栏(浮动),并实现了所有的 File、Edit 和 Help 菜单项,个中包罗最近利用的文件列表和打印以及上下文相关的辅佐,所有这些内容都包括在一个完全徽标兼容的单文档界面 (SDI)、多 SDI 或多文档界面 (MDI) 应用措施中。作为基于文档的应用措施框架,没有可以或许与 MFC 相对抗的竞争者。
可是,措施员们此刻倾向于构建更多基于 HTML 的应用措施,可能可以或许与业务工具或数据库处事器通信的应用措施,而不是基于文档的应用措施。.NET 框架和 Windows 窗体正是为这一目标而量身定做的。
这并不是说 Windows 窗体不能用来构建优秀的基于文档的应用措施。实际上,由于 Windows 窗体只是 .NET 框架所提供的高出 2000 个类中的一小部门,您所需要的内容很有大概 Windows 窗体并没有提供,而是位于该框架中的其他部门中。譬喻,Windows 窗体自己并不提供任何工具序列化支持,可是 .NET 框架类库的其余部门提供了多种序列化工具图的要领。
这是 MFC 和 Windows 窗体之间的主要区别。MFC 旨在替代基本 Win32 API,但这并不能阻止 Win32 API 增长。事实上,就像 MFC 随时间的不绝增长一样,基本 OS 的成果最少增加了十倍。可是,Windows 窗体只是 Win32 的窗口化部门的替代物。.NET 框架类的其余部门认真替代其余的 Win32。虽然,框架永远不行能替代整个 Win32 API,不外,由于在可预期的将来,大大都要添加到 Windows 中的新成果都要被添加到框架中,替代整个 Win32 API 将是一个将来的方针。
因此,固然 Windows 窗体不能具有 MFC 的全部成果,但它简直提供了一组很强的成果,可以极大地便利客户端应用措施开拓人员,这个中包罗一些 MFC 完全不具备的成果。下面,我们将先容如何从新开始构建应用措施,然后讲授 Visual Studio .NET 2003 为 Windows 窗体 C++ 措施员提供的事情效率改造成果。
从新开始建设 Windows 窗体
#p#分页标题#e#
典范的 Windows 窗体应用措施有至少一个窗体。窗体就是一个窗口,也就是从 Windows 1.0 开始我们所看到的 Microsoft 用户界面单位。凡是,Windows 窗体应用措施中的一个窗体是主窗体,意思是它是应用措施的保留周期内大概显示的所有其他窗体的父级或所有者。该窗体是显示主菜单以及东西栏、任务栏等的位置。主窗体竣事时,应用措施也退出。
应用措施的主窗体可以是一个简朴的动静框、一个对话框、一个 SDI 窗口、一个 MDI 窗口,可能更为巨大的控件,如 Visual Studio .NET 这样的应用措施中具有多个子窗口、东西窗口和浮动东西栏的窗体。
假如您的应用措施极为简朴,可以利用充斥在任何窗口化系统中的简单的动静框来实现它:
#using <mscorlib.dll>
#using <System.dll>
#using <System.Windows.Forms.dll>
void __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
long lpCmdLine,
int nCmdShow)
{
System::Windows::Forms::MessageBox::Show("Hello, Windows Forms");
}
作为 C++ 措施员,您肯定很是熟悉 WinMain 进口点,在托管应用措施中,仍需要该进口点。在我们的第一个 Windows 窗体应用措施中,独一一行实际的代码挪用了 Windows::System::Forms::MessageBox 类的静态 Show 要领,这其实只是挪用包括在 Window::Systems::Forms 定名空间 内的 MessageBox 类的静态要领的长写形式。.NET 框架类库中遍及利用了定名空间来将类、布局、列举等范例脱离为差异的逻辑组。由于有数以千计的 Microsoft 雇员要从事添加 .NET 框架类库的事情,并且有数以百计的第三方组织要扩展该类库,同时有数以百万计的措施员正在实验进修它,因此这种脱离长短常须要的。没有定名空间,就需要回收各类巨大的约定来独一地定名各类工具(像现有的 Win32 API 一样)。
定名空间中的范例的界说位于 .NET 措施集 中。措施集是打包为 DLL 或 EXE 的托管范例的容器。#using 指令用于将措施会合的范例应用到您的应用措施中。譬喻,mscorlib 和 System 措施集提供了根基的 .NET 框架范例,如 int 和 string。System.Windows.Forms 措施集包括了 Windows 窗体范例。
利用 #using 将措施集应用到应用措施中后,就可以以前面讲到的长写形式引用范例,可能,可以利用尺度的 C++ using namespace 语句来省略键入代码的事情:
#using <mscorlib.dll>
#using <System.Windows.Forms.dll>
using namespace System::Windows::Forms;
void __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
long lpCmdLine,
int nCmdShow)
{
MessageBox::Show("Hello, Windows Forms");
}
因此,固然这个简朴的示例很有效地演示了最根基的 .NET 框架和 C++ 的托管扩展的观念,但它并不能很好地演示典范的 Windows 窗体措施。对付真实的应用措施,将需要一个 Form 类(或从 Form 派生的类)的实例,如下所示:
void __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
long lpCmdLine,
int nCmdShow)
{
Form* form = new Form();
...
}
form 变量引用了托管范例的一个实例。托管工具是由 .NET 框架的民众语言运行库 (CLR) 处理惩罚的,它们的保留周期由垃圾接纳器节制的,该接纳器在必然的时间打消分派内存。因此,C++ 措施员无需显式地删除托管范例,可是同样不能指望在任何特按时刻(如封锁范畴时)粉碎工具。
建设窗体后,就需要显示它。假如您曾经看过 Windows 窗体的文档,大概已经留意到了 Form 要领 Show,这意味着:
void __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
long lpCmdLine,
int nCmdShow)
{
Form* form = new Form();
form->Show(); // This is not what you want to do.
}
固然上面的代码可以显示窗体,可是必需眼疾手快才可以看到该窗体,这是因为 Show 以无模式的方法显示窗体。这意味着在 Show 将新的窗体显示到屏幕上之后,会当即将节制权返回给 Main 函数,该函数在返回时将退出历程,同时封锁方才显示不久的窗体。要以有模式的方法显示窗体,文档发起利用 ShowDialog 函数:
#p#分页标题#e#
void __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
long lpCmdLine,
int nCmdShow)
{
Form* form = new Form();
form->ShowDialog(); // This is not quite what you want to do.
}
固然这些代码事实上可以显示一个空窗体,而且在用户封锁它之后才会将节制权返回给 Main 函数,但凡是您并不会编写这样的代码。相反,您将把一个窗体指定为主窗体,使得应用措施的其他部门可以把它看成主窗体来举办会见。为此,可以将主窗体作为一个参数通报给 Windows 窗体的 Application 工具的 Run 要领:
#using <mscorlib.dll>
#using <System.dll>
#using <System.Windows.Forms.dll>
using namespace System::Windows::Forms;
void __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
long lpCmdLine,
int nCmdShow)
{
Application::Run(new Form);
}
Application 类的静态 Run 要领将显示主窗体并开始发送 Windows 动静,直到主窗体封锁为止。主窗体封锁后,Run 将返回,让我们的 Main 函数退出,以便竣事历程。要实际查察这一进程,可以利用下面的呼吁行编译这个小小的 Windows 窗体应用措施:
C:MSDNMYFIRS~1>cl /clr MyFirstApp.cpp
#p#副标题#e#
此刻,编译器已经生成了 MyFirstApp.exe,可以执行它了。封锁窗体时,MyFirstApp.exe 将退出,竣事您的第一个 Windows 窗体应用措施。
要想增添一些趣味,可以在新窗体上配置一个属性。像 .NET 框架类库中的大大都工具一样,Form 工具有一些可以会见的属性、可以挪用的要领和可以处理惩罚的事件。可以直接在 Form 类的实例上配置属性,但凡是我们不会这么做。相反,每个自界说窗体都是一个派生自 Form 的类,而且会初始化本身的属性,如下所示:
__gc class MyForm : public Form
{
public:
MyForm()
{
Text = "Hello, Windows Forms!";
}
};
void __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
long lpCmdLine,
int nCmdShow)
{
Application::Run(new MyForm);
}
在 C++ 的托管扩展中,自界说托管范例是利用 __gc 修饰符声明的。请留意,MyForm 类派生自 Form,然后在结构函数中初始化了它本身的属性。这提供了一个很好的用法模子,如新的 Main 函数中所示,该函数建设了 MyForm 类的一个实例。
但这个窗体仍旧很乏味。除系统提供的特点外,它没有任何交互成果。我们可以通过添加一个按钮来增加一些交互成果,如下所示:
MyForm()
{
Text = "Hello, Windows Forms!";
Button* button = new Button();
button->Text = "Click Me!";
this->Controls->Add(button);
}
向窗体添加按钮就是建设一个新的 Button 工具,配置我们需要的属性,并将其添加到该窗体所打点的控件列表中。固然上面的代码会在窗体上发生一个按钮,在单击它后看上去像是被单击了,但并不会产生此外工作,这是因为您还没有处理惩罚该按钮的 click 事件。您可以这样来处理惩罚该事件:
__gc class MyForm : public Form
{
public:
MyForm()
{
Text = "Hello, Windows Forms!";
Button* button = new Button();
button->Text = "Click Me!";
button->Click += new EventHandler(this, button_click);
this->Controls->Add(button);
}
void button_click(Object* sender, EventArgs* e)
{
MessageBox::Show("Ouch!");
}
};
处理惩罚按钮的 Click 事件涉及两项事情。第一项是建设具有适当签名的处理惩罚措施要领,我们称其为 button_Click。绝大大都 .NET 框架事件的签名都是一个函数,该函数什么都不返回,可是获取两个参数:一个暗示事件的发送方(本例中为按钮)的工具,和一个 System::EventArgs 工具(可能一个从 EventArgs 类派生的工具)的实例。
预订事件所需的第二项内容是在 MyForm 结构函数中利用 += 运算符的行。这种暗示法意味着您要向与特定工具上的特定事件有关的所有其他要领的列表中添加一个要领。这要求 EventHandler 委托工具的一个实例。委托是一个类,该类将对事件的挪用转换为预订该事件的要领的挪用。
请留意,Button 类上的 Click 事件是对 EventHandler 委托的引用,因此,要将本身的要领添加到订户列表中,您还需要建设一个该种类的委托的实例。虽然,搞清楚您所感乐趣的所有事件的委托签名,可能通过手动编写代码来将控件添加到窗体上,很快会成为很乏味的工作。幸运的是,这同样可以制止,因为 Visual Studio .NET 2003 中集成了 Windows Forms for C++。
#p#分页标题#e#
在 Visual Studio .NET 2003 之前,只有 C# 和 Visual Basic .NET 具有可视窗体设计器支持。C++ 的托管扩展没有。很幸运,此刻 Visual Studio .NET 附带了 C++ 的托管扩展的 Windows 窗体设计器。
大大都 Windows 窗体项目都在 New Project 对话框中开始,您可以通过单击 File,指向 New,然后单击 Project,可能通过按 CTRL+SHIFT+N 来会见该对话框。
运行 Windows 应用措施领导时,可以随意选择项目名称和位置,然后就可以在设计器中获得一个空缺窗体。
在 MFC 中,仅对对话框支持拖放设计和用户界面机关。普通视图必需在代码中举办机关。可是,Windows 窗体则以一种统一的方法看待所有的窗体,因此沟通的拖放设计器合用于各类窗体。窗体的范例(有模式或无模式,对话框或视图)取决于它的利用方法,而不是设计方法。
设计器中的 Windows 窗体和 MFC 的下一个重大区别是设计器在代码中而不是单独的资源文件中生存控件和机关信息。这与 MFC 很不沟通,MFC 将 Win32 对话框资源中的对话框机关信息生存在 .rc 文件中。这两种方案都各有优缺点,可是 MFC 措施员很快会留意到个中的差异之处。适应起来需要一个进程。
您该当留意的另一件工作是 C++ 的托管扩展项目领导将实现代码生成到了 .h 文件而不是 .cpp 文件中。这大概是由于 C++ 设计器必需适应现有的设计器体系布局而不是 Visual Studio .NET 2002,尔后者仅支持 C# 和 Visual Basic .NET 这样的语言,这些语言不支解声明和界说代码。生成的头文件(可以通过右键单击设计图面然后选择 View Code 或通过按 F7 来会见)如下所示:
namespace MySecondApp
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
public __gc class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
}
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container * components;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->components = new System::ComponentModel::Container();
this->Size = System::Drawing::Size(300,300);
this->Text = "Form1";
}
};
}
上面的大大都代码该当都是为各人所熟知的,包罗顶部的 using 语句和从 Form 基类派生的自界说窗体。独一一处与您的实现差异的处所是窗体的结构函数中挪用 InitializeComponent 以配置窗体的属性,而不是在结构函数自己中举办配置。之所以这么做,是为了使 Windows 窗体设计器有处所安排初始化窗体上的控件和窗体自己的代码。
Windows 窗体应用措施项目模板发生了一个 .cpp 文件:
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
System::Threading::Thread::CurrentThread->ApartmentState =
System::Threading::ApartmentState::STA;
Application::Run(new Form1());
return 0;
}
以上代码看上去同样很熟悉。Main 函数提供了应用措施的进口点和对 Application::Run 的挪用,传入主窗体类的一个实例。将 ApartmentState 变量配置为单线程单位 (STA),是为了 COM 的适当惰性初始化可以或许在拖放操纵中以用户友好的方法利用,以及宿主 COM 控件。
返回到 InitializeComponent 实现,可以看到窗体设计器在哪里安排了代码。譬喻,将按钮从东西箱拖动到窗体的设计图面将把 InitializeComponent 实现变动为如下所示的代码:
void InitializeComponent(void)
{
this->button1 = new System::Windows::Forms::Button();
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(0, 0);
this->button1->Name = "button1";
this->button1->TabIndex = 0;
this->button1->Text = "button1";
//
// Form1
//
this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
this->ClientSize = System::Drawing::Size(288, 253);
this->Controls->Add(this->button1);
this->Name = "Form1";
this->Text = "Form1";
this->ResumeLayout(false);
}
#p#分页标题#e#
请留意,上面的代码同样与您以前生成的代码很雷同,但它们是由设计器建设的。不幸的是,要使这一历程可以或许靠得住地运行,设计器需要可以或许完全节制 InitializeComponent 要领。事实上,您可以看到领导生成的 InitializeComponent 代码包装在一个区域中(默认环境下将埋没代码),并标志了说明性的注释:
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
这大概看上去像是您首选的编程语言,但 InitializeComponent 实际上是设计器用于打点设计图面的工具模子的序列化形式。固然您可以对这些代码举办某些细微的变动,如变动新按钮的 Text 属性,可是重大的变动大概会被忽略,甚至被删除。我们发起您将自界说窗体初始化放入窗体的结构函数中对 InitializeComponent 的挪用之后,以确保设计器不会粉碎您的代码。
虽然,设计器所带来的长处抵消了它的这种对代码的加害。譬喻,您无须通过编写多行代码来配置窗体或它所包括的控件的属性,只需要右键单击所需的工具并选择 Properties(或按下 F4)来调出选定工具的属性欣赏器。
所有非默认的属性(暗示为以粗体显示的值)城市为您写入 InitializeComponent 要领,您无须再编写这些代码。与此雷同,要选择窗体或窗体的控件的事件以举办处理惩罚,可以单击属性欣赏器窗口顶部的 Events 闪电形图标。
在属性欣赏器窗口中,可以以多种方法实现事件的处理惩罚。一种要领是通过单击和键入在引发事件时要挪用的函数的名称来找出要处理惩罚的选定工具的事件,如 button_Click。在输入事件处理惩罚措施的名称后按 Enter,将把您带到具有该名称和正确的签名的事件处理惩罚措施的正文,您可以当即着手实现:
private: System::Void button_Click(Object* sender, EventArgs* e)
{
}
假如您像一般环境下一样但愿为各个工具处理惩罚的各个事件是独一的,可能您不体贴处理惩罚措施的名称,只需在属性欣赏器中双击该事件的名称,就会按照控件和事件的名称为您生成一个事件处理惩罚措施名称。譬喻,假如在 Form 1 窗体的 Load 事件上双击,事件处理惩罚措施名称将为 Form1_Load。
另外,假如您要处理惩罚工具的默认事件,只需双击工具自己就可以举办处理惩罚 - 这样会像您双击属性欣赏器事件列表中的事件名称一样生成一个事件处理惩罚措施名称。工具的默认事件指的是直观上特定范例最常处理惩罚的事件。譬喻,按钮的默认事件为 Click,窗体的默认事件为 Load。不幸的是,设计器和属性欣赏器都没有提示特定范例的默认事件是什么,可是实践中凡是不会由几多破例景象。
设计器的长处在于您可以在窗体内布置控件的机关,确保整齐地分列所有的元素(如图 1 所示),而不像巨细被调解时的状态(如图 2 所示)。
图 1 抱负巨细且整齐机关的窗体
图 2 整齐机关的窗体巨细被调解
用户调解窗体巨细不是为了能有更多灰色的空间,他们是为了可以或许有更多空间用于将数据输入控件中。要到达这一目标,需要从头调解控件的巨细,以占据新的可用空间。这可以通过处理惩罚窗体的 Resize 事件并编写代码来手动完成。可能,也可以通过定位 来实现。
定位是 Windows 窗体为了对窗体和窗体所包括的控件举办自念头关节制而提供的一种要领。默认环境下,所有的控件都定位到左上方,这样,在调解窗体的巨细并移动时,所有的控件都将相对付窗体左上角保持它们的位置。可是,在本例中,最亏得调解窗体巨细时加宽或缩窄文本框控件。这可以通过配置各个文本框的 Anchor 属性来实现。显示控件的属性欣赏器并选择 Anchor 属性,将显示如图 3 所示的编辑器。
图 3 配置 Anchor 属性
要将文本框变动为定位到右边沿以及上边沿和左边沿,只需要单击右侧的定位框,然后将 Anchor 属性变动为 Top、Left 和 Right。这将导致文本框的巨细随窗体的巨细一起变革,如图 4 所示。
图 4 将文本框定位到顶部、左侧和右侧以及将按钮定位到底部和右侧
#p#分页标题#e#
固然默认的定位为左上方,但基础不需要将这些边沿作为定位配置的一部门。譬喻,您可以看到在图 4 中,OK 和 Cancel 按钮被定位到了右下角,这与 Windows 对话框的习惯沟通。
假如您不想生成对话框样式的窗体,而是要生成窗口样式的窗体,定位将不是最好的选择。譬喻,假如您要构建资源打点器样式的应用措施,该应用措施在顶部有一个菜单栏和一个东西栏,底部有一个状态栏,一个树视图和一个列表视图占据其余空间,并用控件之间的拆分器来确定控件所占据的空间,将不能利用定位。此时,您需要利用停靠。
默认环境下,控件的 Dock 属性配置为 None。您可以在属性欣赏器中变动 Dock 属性,要领是选择一个要停靠的边沿,可能选择占据剩余的空间。
譬喻,状态栏、树视图和列表视图的 Dock 属性大概会显示后两者被一个拆分器控件拆分隔来,所有这些都已经布置完毕,您无须编写任何代码。
定位、停靠和拆分并不是分列窗体上的控件的仅有的要领。Windows 窗体还支持分组控件和处理惩罚非凡环境下的自界说机关。另外,Windows 窗体支持在父级内分列窗口、这凡是称为多文档界面 (MDI)。
数据绑定
数据绑定 是指这样一种本领:将一个或多个控件的内容绑定到一个数据源,使恰当个中一方被更新时,另一方也获得更新。数据绑定不仅在 Windows 窗体中受到精采支持,它还完全集成到了 Visual Studio .NET 自己傍边。
从处事器资源打点器将一个表拖放到设计图面大将建设两个组件,一个用于毗连到数据库的毗连 和一个通过毗连在两边之间传送数据的适配器。在设计器中右键单击适配器并选择 Generate Dataset,将建设一个新的数据集,它是一个从 DataSet 派生的类,生成该类专用于生存您从处事器资源打点器拖出来的表的数据。默认的 General Dataset 选项还会建设新数据集的一个实例,用于与控件相关联。
获得数据的源后,就可以将数据绑定到一个或多个控件。Windows 窗体提供了多个数据库绑定控件,包罗 ListBox 和 ComboBox 等,个中 DataGrid 机动性最高。
窗体上有了数据集后,要将数据网格绑定到它并将其作为数据源,只需在属性欣赏器中配置数据网格的 DataSource 和 DataMember 属性,并在加载窗体时填充该数据集:
void InitializeComponent(void)
{
...
this->dataGrid1->DataMember = "Customers";
this->dataGrid1->DataSource = this->dataSet11;
...
}
private: System::Void Form1_Load(System::Object* sender, System::EventArgs* e)
{
sqlDataAdapter1->Fill(dataSet11);
}
以上只是数据绑定的一般用途以及数据网格的特定用途的冰山一角。有关指向更大都据绑定资源的链接,请参阅后头的“参考”部门。
从 MFC 迁移
作为 MFC 措施员,您花在现有代码基上的时间与精神必然长短常多的。将 MFC 代码迁移到 .NET 框架需要举办仔细的筹划。以下是一些留意事项:
• |
假如可以遭受得了从新开始,将可以或许获得可维护性最好的代码基,可是耗时最长。 |
• |
假如您的大大都 MFC 代码在 COM 控件中(可能可以迁移到 COM 控件),您就可以利用 Windows 窗体作为这些控件的宿主,并为框架编写新的托管代码。 |
• |
假如您需要进级 MFC 应用措施自己,可以利用 MFC 7.1 提供的成果,将 Windows 窗体控件宿主为 COM 控件,仍旧保存 MFC 代码为非托管。有关指向以上方案的具体信息的链接,请参阅“参考”部门。 |
• |
假如您想要在 Windows 窗体应用措施中利用托管代码,可是要制止利用 COM Interop 的开销,可以打消 MFC 项目标“Use Managed Extensions”的选项,以便可以或许在沟通的代码中殽杂利用托管和非托管范例。有关指向以上方案的具体信息的链接,也请参阅“参考”部门。 |
#p#分页标题#e#
合用于您的选项要视详细环境而定,可是一般说来,我们发起您回收您本身可以编写 .NET 框架的大部门新代码的计策,固然这意味着您所生成的一些 Windows 窗体成果原本是在 MFC 中开始相识并喜欢上的。
小结
本文先容了一些最引人注目标新 Windows 窗体成果,可是 Windows 窗体具有更多成果,如全自动陈设、对话框数据互换和验证、MDI 应用措施、绘制和打印(包罗打印预览)、用户控件、自界说组件和设计时支持、清单和范例化资源、非编译资源当地化和应用措施配置等等。
对付 MFC 和 Windows 窗体的较量,您需要紧记的一点是它们是在很是差异的时代为了办理大不沟通的问题而别离构建的。MFC 是一个基于文档的应用措施框架。Windows 窗体是一个 n 层应用措施的窗口化库。两者之间存在区别很正常。个中一些区别,如定位和停靠,使得 Windows 窗体更具优势。其他的区别,如工具序列化,存在于 .NET 框架类库的其他部门中。还有一些成果基础不存在,这正是举办基于文档的应用措施开拓的有趣之处。
不外,有两件事很是清楚:Microsoft 正在大踏步靠向托管代码,而托管代码的优势长短常引人注目标。.NET 框架提供了内存和安详性两者的自动处理惩罚,从而可以或许获得更为靠得住的应用措施,并可以提高开拓人员的事情效率。.NET 框架类库提供了一个大型、资源富厚和统一的类库。有了这样的组合,我们将可以或许多快好省地构建 Windows 应用措施。