`
阿尔萨斯
  • 浏览: 4166760 次
社区版块
存档分类
最新评论

使用 Microsoft.NET Frameworks 创建Windows应用程序

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>

使用 Microsoft.NET Frameworks 创建基于 Windows 的应用程序

Shawn Burke
Microsoft Corporation
2000年9月

摘要: :本文介绍了 Win 表单这一新的窗体程序包,借助这一程序包,开发人员能够充分利用 Microsoft Windows 操作系统所提供的 UI 功能。

目录



简介

目前 Web 已成了街谈巷议的话题,看起来好像 Microsoft® Visual Studio® 开发系统对创建基于 Microsoft Windows® 的传统应用程序的支持有所减弱。实际上,Microsoft 对基于 Windows 的应用程序开发方面的投资在不断加大。

Win 表单是一个新的窗体程序包,借助这一程序包,开发人员能够充分利用 Microsoft Windows® 操作系统所提供的丰富的用户界面功能,创建基于 Windows 的应用程序。Win Forms 是新的 Microsoft®.NET 平台的一个组成部分,它提供了许多新技术,包括通用的应用程序框架、可管理的执行环境、一体化的安全性以及面向对象的设计原则。而且,Win Forms 全面支持快速简便地接入 Web Services 以及建立丰富的基于 ADO+ 数据模型的数据感知应用程序。得益于 Visual Studio 中新的共享开发环境,开发人员能够使用包括 Microsoft Visual Basic® 和 C# 在内的任何支持 .NET 平台的语言创建 Win Forms 应用程序。


介绍 Win Forms

就像刚才所说的,Win Forms 是专用于 Windows 客户机 UI 编程的 .NET Framework 的命名空间。它与 ASP+ UI 程序包(即 Web Forms)共享同样的设计原则,但其类和实现却全然不同。在 Microsoft Win32® API 和 Web 组件之间没有魔术般变形的类。就像所有的 .NET Frameworks 一样,一致性已成为优先考虑的问题。其目的是为了 Win Forms 开发人员能够迅速适应在 Web Forms 中编写代码,反之亦然。例如,所有命名空间都有 Button 类,每一个都有文本、默认的 OnClick 事件以及 ForeColorBackColorFont 属性。

Win Forms 的所有控件都基于 System.WinForms.Control 类。Control 已内置了所有基本的 HWND 功能,并且它能处理我们已经熟悉并喜爱的绝大多数通用 WM_xxxx 消息。RichControl 由 Control 派生而来,其中添加了布局逻辑和绘图代码。System.WinForms 命名空间中的绝大多数控件实际上都由 RichControl 派生而来。ScrollableControl 能够支持窗口客户区域的滚动。一般情况下,对滚动功能的支持是通过 ContainerControl 实现的,后者由 ScrollableControl 派生而来,并增加了对管理子控件、焦点问题和跨栏的支持。Form 由 ContainerControl 派生而来,是 Win Form 的顶级控件,它带有控制标题栏、系统菜单、非矩形窗口和默认控件的属性。UserControl 也由 ContainterControl 派生而来,是开发人员能够创建的控件的基本类。UserControl 一般用于托管其它子控件,但对于外部客户机来说,它又是作为单个单元出现的。UserControl 和 Form 在 Microsoft® Visual Studio.NET 中都有可视设计器,您会找到用于添加和设计由其所派生的类的项。

图 1. Win Forms 控件层次结构

既然我们已了解 Win Forms 的(最)基本方面,让我们揭开它的面纱,看看其表面下的一些相当不错的功能。


更好的易学易用性

Win Forms 的主要目的是尽可能地提高定位到 Win32 平台的开发人员的工作效率。无论是图形设备界面 (GDI) 还是窗口状态管理,为 Win32 编程通常都是很困难的。例如,类似 WS_BORDER 或 WS_CAPTION 的一些窗口样式只能在创建窗口时指定或修改。而 WS_VISIBLE 或 WS_CHILD 等其它窗口样式则可以对已创建的窗口进行修改。Win Forms 尽力消除了这些细微的差别,并确保操作过程始终保持一致性。可以随时地、不限次序地对 Win Forms 控件的属性进行设置,总能产生预期效果。如果改动过程需要创建新的 HWND,Win Forms 框架能够自动地、透明地重新生成窗口,并为其应用相适宜的所有设置。

由控件获得通知或事件在 Win Forms 中也要容易得多。Win Forms 事件都基于称为 Delegates 的一个通用语言运行时功能。Delegates 从本质上讲是对类型安全的、可靠的函数指针。对于任一控件的任一事件,都可以添加代理处理程序;绝不会强迫您创建派生类以通过替代处理事件,创建事件映射,或仅为处理一个事件而为类的所有事件实施一个接口。也可以通过替代派生类处理事件,但这种方式一般用于控件创建者或更为高级的应用。汇集某一按钮的 Click 事件相当简单:

public class ButtonClickForm: System.WinForms.Form {private System.WinForms.Button button1;public ButtonClickForm() {// 创建按钮button1 = new System.WinForms.Button();      // 添加处理程序button1.AddOnClick(new System.EventHandler(button1_Click));// 将按钮添加到窗体中this.Controls.Add(button1);  }private void button1_Click(object sender, EventArgs e) {MessageBox.Show("button1 clicked!");  }    }

这里,我们创建了一个按钮,并添加了一个名为 button1_Click 的处理程序方法,通过短短几行代码,在单击该按钮后,将调用这一方法。请注意,即使处理程序方法被标记为专用,创建这一挂钩的代码仍可以使用该方法,单击按钮后,按钮将能够激活这一方法的事件。

启动 Win Forms 项目的过程也得到了简化。使用 Visual Studio.NET 创建 Win Forms 项目的过程只会创建一个要编译的项目文件:Form1.cs。没有头文件,没有接口定义文件,没有引导程序文件,没有资源文件,没有库文件。项目所需的所有信息都包含在窗体的代码中。这样做有一个好处:项目由一个简单的单窗体应用程序扩展到复杂的、带有多个代码文件的多窗体应用程序要方便得多。链接过程不需要中间对象文件,只有代码和已构建的、受管理的所有 DLL。只要您习惯了这一方法,就能明显地感觉到创建 .NET Framework 应用程序和创建 C/C++ 应用程序之间复杂性的不同。因为信息仅仅包含在代码文件中,在 Visual Studio.NET 环境外创建版本的过程也非常容易,无论是 Visual Basic 代码、C# 代码,还是任何其它语言编写的针对 .NET Framework 的代码。

因为 Win Forms 建立在通用语言运行时的基础之上,开发人员可以任选目前针对通用语言运行时的众多语言中的一种,构建 Win32 应用程序。开发人员现在可以使用多种语言编写 Win Forms 应用程序(或 Web Forms 应用程序或 Data 应用程序):从 C# 到 COBOL 到 Eiffel 再到 Perl 等等,中间还有很多种(上一次计数是 17 种)。方便易用再加上广泛的应用场合相得益彰,为开发人员提供了深厚的基础,使他们能够迅速有效地使用 Win Forms 构建实用的应用程序。


布局

如果您曾尝试创建能够正常调整大小的窗体,您就会知道这一过程有多么困难。Microsoft Foundation Classes (MFC) 或早期的 Visual Basic 版本没有对这一功能提供内置的支持。然而现在只需几行代码(通常情况下您甚至不需要编写这些代码,因为在设计时就能通过 Property Browser 实现这些功能!),即可创建能够正常调整大小的对话框。

基本布局由两条组成:Anchoring 和 Docking。RichControl 有一个 Anchor 属性,它是一种枚举类型,可以用“或”操作将这些值组合在一起,以说明控件将与其父控件的某一边保持恒定距离。例如,如果您将一个按钮置于窗体上,并将 Anchor 属性设置为 AnchorStyles.BottomRight,则在调整按钮的大小时,按钮将与窗体的底边和右边保持同一距离。此外,如果将 Anchor 设置为 AnchorStyles.All,则按钮的各个边都与窗体的对应边保持同一距离,在调整按钮大小时仍要满足这些约束条件。

Docking 实际上是 Anchoring 的一个特殊情况。RichControlDock 属性说明控件要将自身固定到其父控件的哪一边。Docking 可以是 Top、Left、Right、Bottom 或 Fill。在每种情况下,控件都将移动到尽量靠近指定边,并调整其大小,以填满那一边。如果父控件的大小有所调整,这一状况仍将保持。将一个控件移动到父控件的底端,并将 Anchor 设置为 AnchorStyle.BottomLeftRight,可以模拟 Docking Bottom。在此处的示例中,列表框是 Docked Left,按钮与窗体的顶端、左边和右边保持恒定距离,由此它们保持了相对位置和大小。下面的示例对话框(图 2)完全使用 Visual Studio.NET 中的 Win Forms 设计器创建,只花了两分钟的时间,没有编写一行代码。

图 2. 使用 Win Forms 设计器所创建的可调整大小的对话框

// ResizableSample.csnamespace ResizableSampleNamespace {    using System;using System.Drawing;using System.ComponentModel;using System.WinForms;/// <summary>///    ResizableSample 的摘要说明。/// </summary>public class ResizableSample : System.WinForms.Form {/// <summary> ///    为 Win Forms 设计器所要求 /// </summary>private System.ComponentModel.Container components;private System.WinForms.Button button3;private System.WinForms.Button button2;private System.WinForms.Button button1;private System.WinForms.ListBox listBox1;public ResizableSample() {// 为 Win Form 设计器支持所要求InitializeComponent();        }/// <summary>///    释放正在使用的所有资源/// </summary>public override void Dispose() {base.Dispose();components.Dispose();        }/// <summary>///    应用程序的主入口点。/// </summary>public static void Main(string[] args) {Application.Run(new ResizableSample());        }/// <summary>        ///    设计器支持所要求的方法 — 不要用编辑器        ///    修改这一方法的内容/// </summary>private void InitializeComponent()   {this.components = new System.ComponentModel.Container();this.button2 = new System.WinForms.Button();this.button3 = new System.WinForms.Button();this.button1 = new System.WinForms.Button();this.listBox1 = new System.WinForms.ListBox();//@design this.TrayLargeIcon = false;//@design this.TrayHeight = 0;this.Text = "Resizable Dialog";this.IMEMode = System.WinForms.IMEMode.Off;this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);this.ClientSize = new System.Drawing.Size(256, 173);button2.Location = new System.Drawing.Point(152, 60);button2.Size = new System.Drawing.Size(92, 32);button2.TabIndex = 2;button2.Anchor = System.WinForms.AnchorStyles.TopLeftRight;button2.Text = "Cancel";button3.Location = new System.Drawing.Point(152, 120);button3.Size = new System.Drawing.Size(92, 44);button3.TabIndex = 3;button3.Anchor = System.WinForms.AnchorStyles.All;button3.Text = "Filler";button1.Location = new System.Drawing.Point(152, 8);button1.Size = new System.Drawing.Size(92, 32);button1.TabIndex = 1;button1.Anchor = System.WinForms.AnchorStyles.TopLeftRight;button1.Text = "OK";listBox1.Size = new System.Drawing.Size(120, 173);listBox1.Dock = System.WinForms.DockStyle.Left;listBox1.TabIndex = 0;listBox1.Items.All = new object[] {"Item One","Item Two","Item Three","Item Four"};this.Controls.Add(button3);this.Controls.Add(button2);this.Controls.Add(button1);this.Controls.Add(listBox1);   }    }}


GDI+

Win Forms 全面利用了 GDI+ 这一 Microsoft 下一代的二维图形系统。Win Forms 中的图形编程模式完全是面向对象的,各式各样的画笔、笔刷、图像和其它图形对象与 .NET Framework 的其它部分一样,遵循了简单易用的指导方针。开发人员目前可以使用相当不错的一些绘图新功能,如 alpha 混色、渐变色、纹理、消除锯齿以及采用除位图外的其它图像格式。与 Windows 2000 操作系统分层和透明的窗口功能配合使用,开发人员能够毫不费力地创建丰富的、更为图形化的 Win32 应用程序。

如果触发了控件的 OnPaint 事件,能够由 PaintEventArgs 访问的 System.Drawing.Graphics 对象就成为一个 GDI+ 图形对象。图形对象能够执行的所有操作都通过 GDI+ 实施。作为一个示例,使用 GDI+ 创建一个绘制渐变背景的按钮。

图 3. 使用 GDI+ 创建的按钮

以下是实现这一按钮的代码:

public class GradientButton : Button {// 保留颜色设置的成员private Color startColor;private Color endColor;            // 书写文字时我们将需要它private static StringFormat format = new StringFormat();public GradientButton() : base() {// 初始化颜色 startColor = SystemColors.InactiveCaption;endColor = SystemColors.ActiveCaption;format.Alignment = StringAlignment.Center;format.LineAlignment = StringAlignment.Center;    }            /// <summary>/// 渐变色的终止颜色// </summary>public Color EndColor {get {return this.endColor;         }set {this.endColor = value;// 如有必要,则导致重新绘制if (this.IsHandleCreated && this.Visible) {Invalidate();            }         }   }            /// <summary>/// 渐变色的起始颜色// </summary>public Color StartColor {get {return this.startColor;         }set {this.startColor = value;// 如有必要,则导致重新绘制if (this.IsHandleCreated && this.Visible) {Invalidate();           }        }   }    protected override void OnPaint(PaintEventArgs pe) {// 绘制按钮的常规背景以形成 // 边框,等等。              base.OnPaint(pe);Graphics g = pe.Graphics;Rectangle clientRect = this.ClientRectangle;// 缩小矩形,以免绘制时出界clientRect.Inflate(-1,-1);// 创建渐变笔刷,从// 左上角运行到右下角。Brush backgroundBrush = new LinearGradientBrush(new Point(clientRect.X,clientRect.Y), new Point(clientRect.Width, clientRect.Height), startColor, endColor);// 以渐变色填充背景....g.FillRectangle(backgroundBrush, clientRect);// 在客户机区域的中间书写文字。g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), clientRect, format);   }}

就像您所看到的,这并不是非常困难。得益于 Win Forms 和 GDI+ 面向对象的设计,无需编写任何复杂的代码,即可实现我们的 GradientButton,并且在设计器中,可以通过 Property Browser 操作 TextFontStartColorEndColor


访问底层系统

许多框架的一个缺点就是:如果人们编写的应用程序类型与示例和演示中的严格一致,则这些框架的效果相当不错,但有时开发人员发现,一旦他们希望用框架进行一些有创造性的工作,某些情况下就会碰到障碍或遭到失败。如果遇到这一情况,Win Forms 框架自始至终都能够允许开发人员访问系统基础结构。当然,希望 Win Forms 这样一个设计优良的框架不会使用户遭遇这种情况,但可能发生的情况几乎是无限的。所有的控件都有 Handle 属性,允许访问控件的窗口句柄 (HWND),GDI 对象也提供了类似的句柄访问过程。而且,Control 实际上拥有一个名为 WndProc 的受保护的虚拟方法,对于少数 Win Forms 尚不能支持的消息,可以替代该方法,添加处理方式。

例如,假设您的应用程序是资源密集型的,需要响应 WM_COMPACTING。如果系统检测到内存不足,会向所有高层窗口广播 WM_COMPACTING,您就会知道 Win Forms 框架对这一消息没有提供内置支持,由此,可以添加如下处理过程:

/// <summary>///    Win32Form1 的摘要说明。/// </summary>public class CompactableForm : System.WinForms.Form {private EventHandler handler;public void AddOnCompacting(EventHandler h) {handler = (EventHandler) Delegate.Combine(handler, h);}protected override void OnCompacting(EventArgs e) {// 查看运行时系统能否释放任何东西System.GC.Collect();// 调用任一处理程序。if (handler != null) handler(this, e);   }public void RemoveOnCompacting(EventHandler h) {handler = (EventHandler) Delegate.Remove(handler, h);}protected override void WndProc(ref Message m) {case (m.msg) {case win.WM_COMPACTING:OnCompacting(EventArgs.Empty);break;      }base.WndProc(m);   }    }

只需数行代码,当系统试着收集未用资源时,利用新的 CompactableForm 类或由此派生的类即可得到通知,并作出响应。


结论

尽管在许多开发人员的计划中,针对 Web 的开发是当前工作的重点,而定位于熟悉的 Win32 平台仍然是一个不得不面对的情况。有了 Win Forms,Windows 开发人员无论是新手还是老手,都会发现使用丰富的接口创建复杂的应用程序是一个很方便的过程,而这些接口与 .NET Framework 中具有 Web 和数据功能的许多技术配合良好。

通过利用跨语言继承、碎片收集和安全性等通用语言运行时提高工作效率的优秀功能,开发人员将从 .NET Framework 和 Win Forms 中获益。




使用 Microsoft.NET Frameworks 创建基于 Windows 的应用程序

Shawn Burke
Microsoft Corporation
2000年9月

摘要: :本文介绍了 Win 表单这一新的窗体程序包,借助这一程序包,开发人员能够充分利用 Microsoft Windows 操作系统所提供的 UI 功能。

目录



简介

目前 Web 已成了街谈巷议的话题,看起来好像 Microsoft® Visual Studio® 开发系统对创建基于 Microsoft Windows® 的传统应用程序的支持有所减弱。实际上,Microsoft 对基于 Windows 的应用程序开发方面的投资在不断加大。

Win 表单是一个新的窗体程序包,借助这一程序包,开发人员能够充分利用 Microsoft Windows® 操作系统所提供的丰富的用户界面功能,创建基于 Windows 的应用程序。Win Forms 是新的 Microsoft®.NET 平台的一个组成部分,它提供了许多新技术,包括通用的应用程序框架、可管理的执行环境、一体化的安全性以及面向对象的设计原则。而且,Win Forms 全面支持快速简便地接入 Web Services 以及建立丰富的基于 ADO+ 数据模型的数据感知应用程序。得益于 Visual Studio 中新的共享开发环境,开发人员能够使用包括 Microsoft Visual Basic® 和 C# 在内的任何支持 .NET 平台的语言创建 Win Forms 应用程序。


介绍 Win Forms

就像刚才所说的,Win Forms 是专用于 Windows 客户机 UI 编程的 .NET Framework 的命名空间。它与 ASP+ UI 程序包(即 Web Forms)共享同样的设计原则,但其类和实现却全然不同。在 Microsoft Win32® API 和 Web 组件之间没有魔术般变形的类。就像所有的 .NET Frameworks 一样,一致性已成为优先考虑的问题。其目的是为了 Win Forms 开发人员能够迅速适应在 Web Forms 中编写代码,反之亦然。例如,所有命名空间都有 Button 类,每一个都有文本、默认的 OnClick 事件以及 ForeColorBackColorFont 属性。

Win Forms 的所有控件都基于 System.WinForms.Control 类。Control 已内置了所有基本的 HWND 功能,并且它能处理我们已经熟悉并喜爱的绝大多数通用 WM_xxxx 消息。RichControl 由 Control 派生而来,其中添加了布局逻辑和绘图代码。System.WinForms 命名空间中的绝大多数控件实际上都由 RichControl 派生而来。ScrollableControl 能够支持窗口客户区域的滚动。一般情况下,对滚动功能的支持是通过 ContainerControl 实现的,后者由 ScrollableControl 派生而来,并增加了对管理子控件、焦点问题和跨栏的支持。Form 由 ContainerControl 派生而来,是 Win Form 的顶级控件,它带有控制标题栏、系统菜单、非矩形窗口和默认控件的属性。UserControl 也由 ContainterControl 派生而来,是开发人员能够创建的控件的基本类。UserControl 一般用于托管其它子控件,但对于外部客户机来说,它又是作为单个单元出现的。UserControl 和 Form 在 Microsoft® Visual Studio.NET 中都有可视设计器,您会找到用于添加和设计由其所派生的类的项。

图 1. Win Forms 控件层次结构

既然我们已了解 Win Forms 的(最)基本方面,让我们揭开它的面纱,看看其表面下的一些相当不错的功能。


更好的易学易用性

Win Forms 的主要目的是尽可能地提高定位到 Win32 平台的开发人员的工作效率。无论是图形设备界面 (GDI) 还是窗口状态管理,为 Win32 编程通常都是很困难的。例如,类似 WS_BORDER 或 WS_CAPTION 的一些窗口样式只能在创建窗口时指定或修改。而 WS_VISIBLE 或 WS_CHILD 等其它窗口样式则可以对已创建的窗口进行修改。Win Forms 尽力消除了这些细微的差别,并确保操作过程始终保持一致性。可以随时地、不限次序地对 Win Forms 控件的属性进行设置,总能产生预期效果。如果改动过程需要创建新的 HWND,Win Forms 框架能够自动地、透明地重新生成窗口,并为其应用相适宜的所有设置。

由控件获得通知或事件在 Win Forms 中也要容易得多。Win Forms 事件都基于称为 Delegates 的一个通用语言运行时功能。Delegates 从本质上讲是对类型安全的、可靠的函数指针。对于任一控件的任一事件,都可以添加代理处理程序;绝不会强迫您创建派生类以通过替代处理事件,创建事件映射,或仅为处理一个事件而为类的所有事件实施一个接口。也可以通过替代派生类处理事件,但这种方式一般用于控件创建者或更为高级的应用。汇集某一按钮的 Click 事件相当简单:

public class ButtonClickForm: System.WinForms.Form {private System.WinForms.Button button1;public ButtonClickForm() {// 创建按钮button1 = new System.WinForms.Button();      // 添加处理程序button1.AddOnClick(new System.EventHandler(button1_Click));// 将按钮添加到窗体中this.Controls.Add(button1);  }private void button1_Click(object sender, EventArgs e) {MessageBox.Show("button1 clicked!");  }    }

这里,我们创建了一个按钮,并添加了一个名为 button1_Click 的处理程序方法,通过短短几行代码,在单击该按钮后,将调用这一方法。请注意,即使处理程序方法被标记为专用,创建这一挂钩的代码仍可以使用该方法,单击按钮后,按钮将能够激活这一方法的事件。

启动 Win Forms 项目的过程也得到了简化。使用 Visual Studio.NET 创建 Win Forms 项目的过程只会创建一个要编译的项目文件:Form1.cs。没有头文件,没有接口定义文件,没有引导程序文件,没有资源文件,没有库文件。项目所需的所有信息都包含在窗体的代码中。这样做有一个好处:项目由一个简单的单窗体应用程序扩展到复杂的、带有多个代码文件的多窗体应用程序要方便得多。链接过程不需要中间对象文件,只有代码和已构建的、受管理的所有 DLL。只要您习惯了这一方法,就能明显地感觉到创建 .NET Framework 应用程序和创建 C/C++ 应用程序之间复杂性的不同。因为信息仅仅包含在代码文件中,在 Visual Studio.NET 环境外创建版本的过程也非常容易,无论是 Visual Basic 代码、C# 代码,还是任何其它语言编写的针对 .NET Framework 的代码。

因为 Win Forms 建立在通用语言运行时的基础之上,开发人员可以任选目前针对通用语言运行时的众多语言中的一种,构建 Win32 应用程序。开发人员现在可以使用多种语言编写 Win Forms 应用程序(或 Web Forms 应用程序或 Data 应用程序):从 C# 到 COBOL 到 Eiffel 再到 Perl 等等,中间还有很多种(上一次计数是 17 种)。方便易用再加上广泛的应用场合相得益彰,为开发人员提供了深厚的基础,使他们能够迅速有效地使用 Win Forms 构建实用的应用程序。


布局

如果您曾尝试创建能够正常调整大小的窗体,您就会知道这一过程有多么困难。Microsoft Foundation Classes (MFC) 或早期的 Visual Basic 版本没有对这一功能提供内置的支持。然而现在只需几行代码(通常情况下您甚至不需要编写这些代码,因为在设计时就能通过 Property Browser 实现这些功能!),即可创建能够正常调整大小的对话框。

基本布局由两条组成:Anchoring 和 Docking。RichControl 有一个 Anchor 属性,它是一种枚举类型,可以用“或”操作将这些值组合在一起,以说明控件将与其父控件的某一边保持恒定距离。例如,如果您将一个按钮置于窗体上,并将 Anchor 属性设置为 AnchorStyles.BottomRight,则在调整按钮的大小时,按钮将与窗体的底边和右边保持同一距离。此外,如果将 Anchor 设置为 AnchorStyles.All,则按钮的各个边都与窗体的对应边保持同一距离,在调整按钮大小时仍要满足这些约束条件。

Docking 实际上是 Anchoring 的一个特殊情况。RichControlDock 属性说明控件要将自身固定到其父控件的哪一边。Docking 可以是 Top、Left、Right、Bottom 或 Fill。在每种情况下,控件都将移动到尽量靠近指定边,并调整其大小,以填满那一边。如果父控件的大小有所调整,这一状况仍将保持。将一个控件移动到父控件的底端,并将 Anchor 设置为 AnchorStyle.BottomLeftRight,可以模拟 Docking Bottom。在此处的示例中,列表框是 Docked Left,按钮与窗体的顶端、左边和右边保持恒定距离,由此它们保持了相对位置和大小。下面的示例对话框(图 2)完全使用 Visual Studio.NET 中的 Win Forms 设计器创建,只花了两分钟的时间,没有编写一行代码。

图 2. 使用 Win Forms 设计器所创建的可调整大小的对话框

// ResizableSample.csnamespace ResizableSampleNamespace {    using System;using System.Drawing;using System.ComponentModel;using System.WinForms;/// <summary>///    ResizableSample 的摘要说明。/// </summary>public class ResizableSample : System.WinForms.Form {/// <summary> ///    为 Win Forms 设计器所要求 /// </summary>private System.ComponentModel.Container components;private System.WinForms.Button button3;private System.WinForms.Button button2;private System.WinForms.Button button1;private System.WinForms.ListBox listBox1;public ResizableSample() {// 为 Win Form 设计器支持所要求InitializeComponent();        }/// <summary>///    释放正在使用的所有资源/// </summary>public override void Dispose() {base.Dispose();components.Dispose();        }/// <summary>///    应用程序的主入口点。/// </summary>public static void Main(string[] args) {Application.Run(new ResizableSample());        }/// <summary>        ///    设计器支持所要求的方法 — 不要用编辑器        ///    修改这一方法的内容/// </summary>private void InitializeComponent()   {this.components = new System.ComponentModel.Container();this.button2 = new System.WinForms.Button();this.button3 = new System.WinForms.Button();this.button1 = new System.WinForms.Button();this.listBox1 = new System.WinForms.ListBox();//@design this.TrayLargeIcon = false;//@design this.TrayHeight = 0;this.Text = "Resizable Dialog";this.IMEMode = System.WinForms.IMEMode.Off;this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);this.ClientSize = new System.Drawing.Size(256, 173);button2.Location = new System.Drawing.Point(152, 60);button2.Size = new System.Drawing.Size(92, 32);button2.TabIndex = 2;button2.Anchor = System.WinForms.AnchorStyles.TopLeftRight;button2.Text = "Cancel";button3.Location = new System.Drawing.Point(152, 120);button3.Size = new System.Drawing.Size(92, 44);button3.TabIndex = 3;button3.Anchor = System.WinForms.AnchorStyles.All;button3.Text = "Filler";button1.Location = new System.Drawing.Point(152, 8);button1.Size = new System.Drawing.Size(92, 32);button1.TabIndex = 1;button1.Anchor = System.WinForms.AnchorStyles.TopLeftRight;button1.Text = "OK";listBox1.Size = new System.Drawing.Size(120, 173);listBox1.Dock = System.WinForms.DockStyle.Left;listBox1.TabIndex = 0;listBox1.Items.All = new object[] {"Item One","Item Two","Item Three","Item Four"};this.Controls.Add(button3);this.Controls.Add(button2);this.Controls.Add(button1);this.Controls.Add(listBox1);   }    }}


GDI+

Win Forms 全面利用了 GDI+ 这一 Microsoft 下一代的二维图形系统。Win Forms 中的图形编程模式完全是面向对象的,各式各样的画笔、笔刷、图像和其它图形对象与 .NET Framework 的其它部分一样,遵循了简单易用的指导方针。开发人员目前可以使用相当不错的一些绘图新功能,如 alpha 混色、渐变色、纹理、消除锯齿以及采用除位图外的其它图像格式。与 Windows 2000 操作系统分层和透明的窗口功能配合使用,开发人员能够毫不费力地创建丰富的、更为图形化的 Win32 应用程序。

如果触发了控件的 OnPaint 事件,能够由 PaintEventArgs 访问的 System.Drawing.Graphics 对象就成为一个 GDI+ 图形对象。图形对象能够执行的所有操作都通过 GDI+ 实施。作为一个示例,使用 GDI+ 创建一个绘制渐变背景的按钮。

图 3. 使用 GDI+ 创建的按钮

以下是实现这一按钮的代码:

public class GradientButton : Button {// 保留颜色设置的成员private Color startColor;private Color endColor;            // 书写文字时我们将需要它private static StringFormat format = new StringFormat();public GradientButton() : base() {// 初始化颜色 startColor = SystemColors.InactiveCaption;endColor = SystemColors.ActiveCaption;format.Alignment = StringAlignment.Center;format.LineAlignment = StringAlignment.Center;    }            /// <summary>/// 渐变色的终止颜色// </summary>public Color EndColor {get {return this.endColor;         }set {this.endColor = value;// 如有必要,则导致重新绘制if (this.IsHandleCreated && this.Visible) {Invalidate();            }         }   }            /// <summary>/// 渐变色的起始颜色// </summary>public Color StartColor {get {return this.startColor;         }set {this.startColor = value;// 如有必要,则导致重新绘制if (this.IsHandleCreated && this.Visible) {Invalidate();           }        }   }    protected override void OnPaint(PaintEventArgs pe) {// 绘制按钮的常规背景以形成 // 边框,等等。              base.OnPaint(pe);Graphics g = pe.Graphics;Rectangle clientRect = this.ClientRectangle;// 缩小矩形,以免绘制时出界clientRect.Inflate(-1,-1);// 创建渐变笔刷,从// 左上角运行到右下角。Brush backgroundBrush = new LinearGradientBrush(new Point(clientRect.X,clientRect.Y), new Point(clientRect.Width, clientRect.Height), startColor, endColor);// 以渐变色填充背景....g.FillRectangle(backgroundBrush, clientRect);// 在客户机区域的中间书写文字。g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), clientRect, format);   }}

就像您所看到的,这并不是非常困难。得益于 Win Forms 和 GDI+ 面向对象的设计,无需编写任何复杂的代码,即可实现我们的 GradientButton,并且在设计器中,可以通过 Property Browser 操作 TextFontStartColorEndColor


访问底层系统

许多框架的一个缺点就是:如果人们编写的应用程序类型与示例和演示中的严格一致,则这些框架的效果相当不错,但有时开发人员发现,一旦他们希望用框架进行一些有创造性的工作,某些情况下就会碰到障碍或遭到失败。如果遇到这一情况,Win Forms 框架自始至终都能够允许开发人员访问系统基础结构。当然,希望 Win Forms 这样一个设计优良的框架不会使用户遭遇这种情况,但可能发生的情况几乎是无限的。所有的控件都有 Handle 属性,允许访问控件的窗口句柄 (HWND),GDI 对象也提供了类似的句柄访问过程。而且,Control 实际上拥有一个名为 WndProc 的受保护的虚拟方法,对于少数 Win Forms 尚不能支持的消息,可以替代该方法,添加处理方式。

例如,假设您的应用程序是资源密集型的,需要响应 WM_COMPACTING。如果系统检测到内存不足,会向所有高层窗口广播 WM_COMPACTING,您就会知道 Win Forms 框架对这一消息没有提供内置支持,由此,可以添加如下处理过程:

/// <summary>///    Win32Form1 的摘要说明。/// </summary>public class CompactableForm : System.WinForms.Form {private EventHandler handler;public void AddOnCompacting(EventHandler h) {handler = (EventHandler) Delegate.Combine(handler, h);}protected override void OnCompacting(EventArgs e) {// 查看运行时系统能否释放任何东西System.GC.Collect();// 调用任一处理程序。if (handler != null) handler(this, e);   }public void RemoveOnCompacting(EventHandler h) {handler = (EventHandler) Delegate.Remove(handler, h);}protected override void WndProc(ref Message m) {case (m.msg) {case win.WM_COMPACTING:OnCompacting(EventArgs.Empty);break;      }base.WndProc(m);   }    }

只需数行代码,当系统试着收集未用资源时,利用新的 CompactableForm 类或由此派生的类即可得到通知,并作出响应。


结论

尽管在许多开发人员的计划中,针对 Web 的开发是当前工作的重点,而定位于熟悉的 Win32 平台仍然是一个不得不面对的情况。有了 Win Forms,Windows 开发人员无论是新手还是老手,都会发现使用丰富的接口创建复杂的应用程序是一个很方便的过程,而这些接口与 .NET Framework 中具有 Web 和数据功能的许多技术配合良好。

通过利用跨语言继承、碎片收集和安全性等通用语言运行时提高工作效率的优秀功能,开发人员将从 .NET Framework 和 Win Forms 中获益。




分享到:
评论

相关推荐

    c#脱离framework运行教程

    Loader程序不会打开任何窗口,并在启动真正应用程序后立即退出。Loader程序主函数(VC6.0编写)的代码如下: 主函数: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int...

    .net frameworks plugin

    WinPE下.net framework 使用插件。

    VB.net中应用CefSharp.WinForms库构建Chrome内核浏览器实例

    VB.net中应用CefSharp.WinForms库构建Chrome内核浏览器实例源代码,环境为Windows 10,Visual Studio 2015,.Net FrameWorks 4.52。未包含CefSharp.WinForms的Packages文件夹以及bin下面的支持文件,请自行安装调试...

    使用Asp.Net Core MVC / TypeScript简化业务应用程序-.NET开发

    Serenity应用程序平台什么是Serenity平台Serenity是一个ASP.NET MVC / TypeScript应用程序平台,旨在通过serv Serenity应用程序平台简化和缩短以数据为中心的业务应用程序的开发。Serenity平台Serenity是ASP.NET MVC...

    ASP.NET样板-Web应用程序框架-.NET开发

    ASP.NET Boilerplate是一个通用应用程序框架,专门为新的现代Web应用程序设计。 它使用已经熟悉的工具并实现最佳实践。ASP.NET Boilerplate什么是ABP? ASP.NET Boilerplate是专门为新的现代Web应用程序设计的通用...

    Microsoft Windows Script 技術

    ECMAScript Edition 4 共同開發) 的改善包括真實編譯程式碼、具型別與不具型別的變數、類別 (包含繼承、函式多載化 (Function Overloading)、屬性存取子以及其他)、套件、跨語言支援以及存取 .NET Frameworks。

    Windows Mobile .NET Compact Framework 气泡技术示例

    提供一个演示 .NET Compact Framework 的绘图功能的应用程序

    asp.net知识库

    ASP.NET 2.0使用Web Part创建应用程序之二(共二) 体验 .net2.0 的优雅(2) -- ASP.net 主题和皮肤 NET2.0系列介绍(一).NET 2.0 中Web 应用程序主题的切换 ASP.NET 2.0 中Web 应用程序主题的切换 2.0正式版中...

    Net Frameworks3.5.zip

    win10上运行一些程序时,总是提示需要.NET Frameworks3.5,试过各种方法均不行,最终只能选择离线安装,而下载离线文件时,看到有些人竟然要那么多的币,感觉真是浪费,本软件可从这里下载,我也会附上连接大家从相应...

    win2003-64位系统IIS配置方法

    命令:C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\aspnet_regiis.exe –u 2、把IIS切换为32Bit模式运行 命令:Cscript C:\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1 ...

    ASP.NET 5 and MVC 6

    ASP.NET Core MVC is a web application development framework from Microsoft that combines the effectiveness and tidiness of model-view-controller (MVC) architecture, ideas and techniques from agile ...

    Orleans是一个跨平台框架,用于使用.NET构建分布式应用程序-.NET开发

    Orleans建立在.NET开发人员生产力的基础上,并将其带入了分布式应用程序的世界,例如云服务。 Orleans可从单个本地服务器扩展到云中全局分布的高可用性应用程序。 奥尔良采用了对象,接口,异步/等待和尝试/捕获等...

    Pro C# 7: With .NET and .NET Core

    This essential classic title provides a comprehensive foundation in the C# programming language and the frameworks it lives in. Now in its 8th edition, you’ll find all the very latest C# 7.1 and .NET...

    电子书 Microsoft ASP.NET 4 Step by Step

    This book shows you how to write Web applications using Microsoft ASP.NET 4, the most current version of the Microsoft ... ASP.NET has evolved to become one of the most consistent, stable, and feature ...

    DXperience Universal Subscription 13.2.7.14057 source code

    DevExpress .NET 控件和应用程序框架包,完整源码,价值 $1499.99 美金 The DXperience Subscription includes the complete range of DevExpress .NET controls and libraries for all major Microsoft platforms,...

    ASP.NET Core是一个跨平台的.NET框架,用于在Windows,Mac或Linux上构建基于云的现代Web应用程序。-.NET开发

    ASP.NET Core应用程序在.NET Core(一个免费的ASP.NET Core)上运行ASP.NET Core是一个开放源代码和跨平台框​​架,用于构建基于现代云的互联网连接应用程序,例如Web应用程序,IoT应用程序和移动应用程序后端。...

    一个用于在ASP.NET Core Web应用程序中支持API端点的项目。-.NET开发

    一个用于在ASP.NET Core Web应用程序中支持API端点的项目。 ASP.NET Core API端点一个用于在ASP.NET Core Web应用程序中支持API端点的项目。 给个星星! :star:如果您喜欢或正在使用该项目来学习或开始您的解决方案...

    DXperience Universal Subscription 13.2.7.14057 full source code

    DevExpress .NET 控件和应用程序框架包,完整源码,价值 $1499.99 美金 The DXperience Subscription includes the complete range of DevExpress .NET controls and libraries for all major Microsoft platforms,...

    ASP.NET Core Succinctly

    By learning the foundations of the library and understanding the new versions of ASP.NET MVC and Web API, you’ll be equipped with everything you need to build .NET web applications on Windows, Mac, ...

    微软同步软件synctoy20.

    微软给我们展示了一款软件SyncToy v1 ...ScncToy仅支持Windows XP操作系统,同时要求系统中必须安装有Microsoft.NET Frameworks才可以运行。下载安装程序后是一个msi格式的安装文件,运行它即可根据向导轻松完成安装。

Global site tag (gtag.js) - Google Analytics