分享
 
 
 

Henry手记:VB.NET Windows 窗体引介(二)

王朝vb·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Henry手记 - VB.NET Windows 窗体引介(二)

韩睿 ( 12/26/2002)

上一篇发表后,有读者来信和留言,认为是不是太简单了?其实,Henry是有一些私心的,本来我准备继续讨论Datagrid中的事件响应(如双击cell这样的复杂过程),但必须要涉及到事件处理方法的内容,正好本文的结构可以让Henry在适当扩充后达到这一目标。这虽然是个不复杂的问题,但写清楚还是不太容易的,写完此篇后,发现除结构上与原文一致外,已经面目全非了,为了保证对原作者的尊重,只好将此篇剔除出译作的范围,这里有原文的链接,可供读者自行参考。并借此机会对原作者提供的帮助表示感谢。

添加控件

如果没有控件,您的窗体还并不是真正有用。.NET Framework基本类型库提供了大量控件以备使用。你可以使用button, checkbox, textbox, label...如果对于.NET Framework您还是个新手,您还需要研究一下Object派生树。以button控件为例,其派生关系如图1所示:

System.Object

System.MarshalByRefObject

System.ComponentModel.Component

System.Windows.Forms.Control

System.Windows.Forms.ButtonBase

System.Windows.Forms.Button

图1 Button控件派生树

所有控件都是派生自Cotrol类,向窗体中添加一个控件需要以下三个步骤:

(1)定义一个控件变量

(2)实例化控件

(3)把控件加入窗体中

因为VB.NET变量有不同的应用范围,在何处声明一个变量才是最重要的。在一个函数内声明的变量只能在函数内生存。如果您想让您的控件在整个类中都可用,请在类级别上定义它。

实例化一个控件就象实例化其它任何对象一样,使用NEW关键字。一旦您有一个实例化了的控件,你就可以将其加入窗体中去。因为Form类没有诸如Add(Control)这样的方法,你不能直接将控件添加到窗体上去。但是,Form类从Control类继承了Controls属性。在Form类中,您可以使用此属性去获取该Form的System.Windows.Forms.Form.ControlCollection对象。这个System.Windows.Forms.Form.ControlCollection类代表了在窗体中包含的控件的集合。您可以使用它的Add方法往窗体中添加控件,用Remove方法把一个控件从窗体中移除。要理解这三个步骤,以添加一个Button控件为例将代码示例如下:

'声明button变量

Dim Button1 As System.Windows.Forms.Button

'实例化button

Button1 = New System.Windows.Forms.Button()

'将 button 加至窗体

Me.Controls.Add(Button1)

如果您不是只添加一个控件,而是要加入多个控件,一般不要使用Add方法去一个个添加,而是使用AddRange方法去添加一组Control对象。比如,您往窗体中添加一个button(ID:button1),同时添加一个textbox(textbox1),可以这样写:

Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.TextBox1, Me.Button1})

您可以通过设置控件的多个属性去获得您所需要的控件。可以在将其加到窗体之前或之后设置这些属性,但必须是要实例化了控件之后。一个控件的属性通常有控制其大小与位置的Left, Top, Width 和Height。一个Button属性还有Text属性用于显示button对象的文本等等。以下的代码是继续上一节的内容,补充初始化的代码:

Private Button1 As System.Windows.Forms.Button

Private TextBox1 As System.Windows.Forms.TextBox

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.Button1 = New System.Windows.Forms.Button()

Me.TextBox1 = New System.Windows.Forms.TextBox()

Me.SuspendLayout()

'Button1

Me.Button1.Location = New System.Drawing.Point(200, 72)

Me.Button1.Name = "Button1"

Me.Button1.Size = New System.Drawing.Size(96, 56)

Me.Button1.TabIndex = 0

Me.Button1.Text = "Button1"

'TextBox1

Me.TextBox1.Location = New System.Drawing.Point(216, 168)

Me.TextBox1.Name = "TextBox1"

Me.TextBox1.Size = New System.Drawing.Size(64, 21)

Me.TextBox1.TabIndex = 1

Me.TextBox1.Text = "TextBox1"

'Form1

Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)

Me.ClientSize = New System.Drawing.Size(392, 266)

Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.TextBox1, Me.Button1})

Me.Name = "Form1"

Me.Text = "Henry 的窗体"

Me.ResumeLayout(False)

End Sub

这里Henry要解释几个一般不太注意的问题:

(1) 布局事件:在窗体中添加或移除控件,或在控件中添加或移除子控件,窗体/ 控件的边界改变,以及在发生其他可能影响窗体/ 控件的布局时,将会发生 Layout 事件。因此在设置初始化代码时,应该先禁止(挂起)此事件发生,在布局完毕后再恢复。要不然每添加、设置一个控件就会调用一次Layout事件,对窗体进行重新布局,影响工作效率。所以在上例中用Me.SuspendLayout()来挂起Layout事件,在设置完毕后,用Me.ResumeLayout(False)来恢复该事件。

(2) VB.NET的习惯是使用集合、数组来处理以前的个体行为,我们可以从上例中看出。设置控件的位置时,没有用left、right、top等属性来定位,而是使用Location属性来设置该控件左上角的坐标。设置控件大小时,没有用Height、width等属性,而是使用Size。这也表现了VB.NET设计与使用上的一个变革思想,多使用集合,可以提高代码的简洁度,且便于阅读与管理。

(3) Button1与Textbox1的Private声明在后文会详加解释。

事件处理

先前版本的VB是事件驱动的,您可以很方便地编写响应事件的程序代码。比如,您想让按钮Button1响应用户的单击(Click)事件,所有要做的事就是创建一个名为Button1_Click的事件程序(实际上,VB 集成编译环境帮您完成了此工作)。在VB.NET中的事件处理方法,和以前是一样的。当您在设计窗口布署了控件后,可以点击它以告知Visual Studio.NET您想写一段事件处理程序。接下来您将看到如何人工编写该代码,也因此使您明白VB.NET的事件是如何工作的。

对于Windows事件驱动程序而言,不可避免要涉及三个要素:对象、事件、事件处理程序。

那么对于我们这个例子,对应上述要素的各是什么呢?

对象:Button1 事件:Click 事件处理程序:Button1_Click

联系起来用语言描述就是:点击Button1(对象),会激发Click(事件),调用Button1_Click(事件处理程序)。

如果您想让某个对象能够响应事件,就要在声明它时使用WithEvent关键字(WithEvents 关键字指示被声明的对象变量引用可以引发事件的类实例)。例如,当您想让按钮(button)能够响应事件,就要将声明:

Private Button1 As Button

替换为:

Private WithEvents Button1 As Button‘这个声明在后文还会有变化,请读者注意

在变量名前添加WithEvent。

然后,您需要为每个事件创建一段事件处理程序以使对象能够在响应事件时调用。Button1要响应Click事件,您需要有一个Button1_Click过程,并用Handles标识“控件.事件”。

Private Sub Button1_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Button1.Click

'在此写自己的代码

End Sub

Form类和所有的控件类都从Control类继承下了事件。如果您查看一下.NET Framework参考中的System.Windows.Forms.Control类,您将会看到此类有58个事件,包括从Component继承下的Disposed事件(关于Disposed的继承关系,请看Henry的另一篇文档)。还命名了许多新的诸如Click, DoubleClick, GotFocus, LostFocus, KeyUp, KeyDown等事件。

很多新手都会有这样的问题:事件处理程序中的参数Sender与e是什么意思?

(1) sender as object,就一语道破它的来源与用途。object是支持 .NET 框架类层次结构中的所有类,并为派生类提供低级别服务。这是 .NET 框架中所有类的最终超类;它是类型层次结构的根。

一般来说,sender在形参中表示引发事件的源头,即上文所说的三要素中的“对象”。如果在控件引发的事件中写代码的话(就象上例这样),一般都不需要再重新指派,因为它已经默认为是该控件了。当自己写代码来调用某事件程序时,就要注明sender是何物了。

(2) e,表示的是事件数据,就是一个事件激发所需要的状态(参数)信息。在事件引发时不向事件处理程序传递状态信息的事件会将e设为Eventargs。如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。比如Mousedown事件,系统需要判断mouse的位置、判断是左中右等哪个键点击了、判断点击了几下等等,因此该e就成为了System.Windows.Forms.MouseEventArgs类的实例。

当几个控件的事件处理程序是相同时,可以把“对象名.事件名”加至Handles之后,即可在事件引发时,调用同一个事件处理程序。如果处理程序有所不同,可以通过Sender来进行标识,代码如下:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _

Handles Button1.Click, Button2.Click

Select Case sender.name

Case "Button1"

MsgBox("你点击的是button1")

Case "Button2"

MsgBox("你点击的是button2")

End Select

End Sub

注:您将上例中的过程名“Button1_Click”换成“Henry”,再运行一下看,是不是结果是一样的?也就是说您可以自己来编写事件处理程序了,不会再象VB中受到固定模式的多个制约了。(不过建议您还是采用“对象名_事件名”这样的命名方式,以便阅读)

下一节会介绍窗体继承的问题,敬请等待!祝各位新老朋友新年快乐!事业有成!

----

声明:本文版权与解释权归韩睿所有,如需转载,请保留完整的内容及此声明。

QQ: 18349592

E-Mail: henry7685@hotmail.com

请访问本人专栏:http://www.csdn.net/develop/author/netauthor/Latitude/

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有