第八章 用户界面(四)

处理 WinForms 事件和事件模块

在第七章我们讨论过事件(Event)模块,它能够用于处理 WinForms 中的事件。当处理 WinForms 中的事件时,通常会遇到没有完全符合想要事件的情况。例如,当鼠标的左、右键单击时会触发MouseButton 事件,但是,我们可能只希望它响应鼠标左键的单击。这时,用 Event.filter 函数可能会很有用,用它创建一个新的事件,只响应鼠标左键的单击。看下面例子的演示:

openSystem.Windows.Forms

let form =

// create a new form

let temp =
new Form()

// subscribe the mouse click event filtering so it only

// reacts to the left button

temp.MouseClick

|> Event.filter (fun e
-> e.Button =
MouseButtons.Left)

|> Event.add (fun _
-> MessageBox.Show("Leftbutton")|> ignore)

// return the form

temp

Application.Run(form)

这里,函数filter用函数参数检查鼠标左键是否按下,结果事件通过管道传递给 listen 函数,把事件处理程序加到事件中,[ 这一段应该是忘记改了,从程序来看,已经使用事件的 add 函数了] 就如同调用事件的Add 方法一样。可以在事件处理程序中使用 if 表达式来实现,但是,这个技术有它的优势,能够把控制事件触发的逻辑和事件本身发生的事情分离出来。如果愿意,几个事件处理程序能够重用这个新事件。

清单 8-3 演示了如何使用几个事件函数创建一个简单的画图程序(如图 8-5)。这里以另一种方式使用 MouseDown 事件:首先,用它来监视鼠标是否按下;然后,用分区函数(Event.partition)把事件划分到左、右按钮的按下,用它来控制画图的颜色,红和黑:

清单 8-3 用事件实现一个简单的画图程序

open System

open System.Drawing

openSystem.Windows.Forms

let form =

// create the form

let temp =
new Form(Text =
"Scribble !!")

// some refrence cells to hold the applications state

let pointsMasterList = ref []

let pointsTempList = ref []

let mouseDown = ref
false

let pen = ref (new Pen(Color.Black))

// subscribe to the mouse down event

temp.MouseDown.Add(fun _
-> mouseDown := true)

// create a left mouse down and right mouse down events

let leftMouse, rightMouse =

temp.MouseDown

|> Event.partition (fun e
-> e.Button =MouseButtons.Left)

// use the new left and right mouse events to choose thecolor

leftMouse.Add(fun _
-> pen := new Pen(Color.Black))

rightMouse.Add(fun _
-> pen := new Pen(Color.Red))

// the mouse up event handler

let mouseUp _ =

mouseDown := false

if List.length !pointsTempList > 1
then

let points = List.toArray !pointsTempList

pointsMasterList :=

(!pen, points) :: !pointsMasterList

pointsTempList := []

temp.Invalidate()

// the mouse move event handler

let mouseMove (e: MouseEventArgs) =

pointsTempList := e.Location ::!pointsTempList

temp.Invalidate()

// the paint event handler

let paint (e: PaintEventArgs) =

if List.length !pointsTempList > 1
then

e.Graphics.DrawLines

(!pen, List.toArray !pointsTempList)

!pointsMasterList

|> List.iter

(fun (pen, points)
->

e.Graphics.DrawLines(pen, points))

// wire up the event handlers

temp.MouseUp |> Event.add mouseUp

temp.MouseMove

|> Event.filter(fun _
-> !mouseDown)

|> Event.add mouseMove

temp.Paint |> Event.add paint

// return the form object

temp

[<STAThread>]

doApplication.Run(form)

图 8-5. 涂鸦:用事件实现的简单的画图程序

也可以用这种方法把创建的事件发布到窗体的界面上,这样,使用窗体的代码能够利用这些事件。

另外,程序员在处理 Windows 窗体事件时面临的一个很大的问题,就是可用的事件的数量,这是很难做出正确选择的。可能非常奇怪,大多数事件都定义在控件(control)类中,只有少数几个事件专门额外提供。这样使事情变得更容易,因为如果我们使用随控件的事件,那么,它也可以在其他控件上使用。表8-4 提供了Control 类中的常见事件的汇总:

表 8-4 Control 类的事件汇总


事件


描述


Click


该事件是由用户单击控件引起。这是一个高级事件,尽管它通常由用户使用鼠标单击引起,当[ 焦点 ] 在控件上时,也可能由按回车键或空格键引起。有一系列事件 MouseDown、MouseClick、MouseUp,提供有关鼠标动作的详细信息。但是,这些事件提供信息只与鼠标动作有关,因此,通常应该处理单击(Click)事件,而不是这些事件;否则,会导致控件不能按用户所期望的方式响应,因为它只响应鼠标单击,而不响应键盘操作。


DoubleClick


该事件由鼠标双击引用。注意,双击的时间间隔由操作系统决定。程序员处理这个事件应该小心,因为每次触发这个事件,而在此之前还要触发单击事件。就是说,既要处理这个事件,还要处理单击事件。


Enter


该事件当控件激活时引起,既可以是用户按 Tab 键进入,也可以由程序调用 Select 或 SelectNextControl,还可以由用户单击鼠标而引起。通常使用此控件是用来提请注意它处于活动状态,比如,把背景设置为不同的颜色。注意,在窗体类中这个事件被抑制,应该用 Activated 事件。


Leave


该事件当控件停用时引起。既可以是用户按 Tab 键离开,也可以由程序调用 Select 或SelectNextControl,还可以由用户鼠标单击其他控件而引起。我们可能会想用此事件进行验证,但不应该用,而应该用 Validating和 Validated 事件。

在窗体类中这个事件被抑制,应该用 Activated事件。

[ 是否应该是 Dectivate  ]


KeyPress


该事件是一序列事件中的一部分,用来获得有关键盘状态的详细信息。为了获得第一次按键的详细信息,使用 KeyDown,当键释放时,用 KeyUp。


Move


用户移动控件时引发该事件。


MouseHover


该事件用于发现鼠标是否悬停控件上,能够给用户提供更多有关该控件的信息。对此,事件 MouseEnter、 MouseLeave 也是有用的。


Paint


当 Windows 刷新窗体时引发该事件。如果你想自己绘制控件,应该处理这个事件。更多信息看本章前面的“ Windows 窗体”。


Resize


用户改变窗体大小时引发该事件。用于调整窗体的布局大小时应该处理这个事件。

第八章 用户界面(四),布布扣,bubuko.com

时间: 2024-08-07 12:48:35

第八章 用户界面(四)的相关文章

第八章 用户界面(三)

在 F# 中使用 Visual Studio 窗体设计器 到现在,F# 还没有自己的窗体设计器:然而,由于 .NET 具有很强的互操作性,因此,很容易在 F# 中使用由 Visual Studio 设计器创建的窗体.有两种选择:第一,创建一个 F# 库,然后,在自己的 Windows 窗体中调用这个库中的函数:第二:创建一个窗体库,然后,在 F# 应用程序中使用.下面分别讨论这两种方法,并对比它们的优势与不足:示例都是计算斐波那契数列(Fibonacci),如图 8-4. 警告 本书是有关 F#

第八章 用户界面(一)

在这一章,我们将学习程序员最重要的任务之一:把像素放到屏幕上艺术.在 F# 中,所要做的就是调用库和 API,在这方面有很多选择,因为有了 .NET 平台,就更加多样.第一个选择是要确定是想创建桌面应用程序,它运行在本地,用一系列窗口和控件把信息显示给用户:还是想创建网站应用程序,应用程序的界面用 HTML 定义,然后,通过浏览器渲染. 用 .NET 创建桌面应用程序,可以有四种选择:WinForms.Windows Presentation Foundation (WPF,[ 原文这里有笔误

第八章 用户界面(二)

在 WinForm 上使用控件 控件就是类,派生自 System.Windows.Forms.Control,由此类派生出的任何类都能显示在窗体上,只要将它添加到窗体对象的 Controls 集合中. 现在我们看一下用控件画树形的方法.WinForms 库定义了 TreeView 类,这是专门用于显示树形结构的:自然,我们就用这个控件来显示树.使用 TreeView,需要创建它的实例,并设置属性.调用方法,对它进行配置.最重要的,是将需要显示的结点添加到 Nodes 集合中.这个控件准备好以后,

《大道至简》弟七八章读后感

第七章标题为现实中的软件工程,共分为四小节,标题分别为:1.大公司手中的算盘:2.回到工程的关键点:3.思考项目成本的经理:4.审视AOP:5.审视MDA/MDD.第八章分为七小节分别是:1.软件工程的三个要素的价值:2.其实RUP是一个杂物箱:3.UML与甲骨文之间的异同:4.  经营者离开发者很远,反之亦然:5.  矛盾:实现目标与保障质量:6.枝节与细节:7.灵活的软件工程. 在第七章第一小节中作者向我们介绍了IBM公司的发展状况,并由此讲到其他的大型软件公司,揭示了他们一面打压对手的优势

致初入职场的兄弟姐妹

致初入职场的兄弟姐妹   我很喜欢电影<燃情岁月>中的那句台词--"有些人能够听见自己内心的声音,非常的清楚,他们依循着自己的内心来行事.这些人变得疯狂,或者成为传奇--"(Some people hear their own inner voices with great clearness and they live by what they hear. Such people become crazy, or they become legends. )     这是

【文章内容来自《Android 应用程序开发权威指南》(第四版)】如何设计兼容的用户界面的一些建议(有删改)

最近一直在看的一本书是<Android 应用程序开发权威指南>(第四版),十分推荐.书中讲到了一些用户界面设计的规范,对于初学者我认为十分有必要,在这里码给大家,希望对我们都有用. 在我们设计用户界面的时候,我们总是很多时候通过提供自定义应用资源和代码的方法来支持特定设备配置,但有一点特别需要注意的,那就是我们必须保证我们的设计方案有足够的灵活性来应对各种变化,让他们变得简单,而不是过度的挤压他们,一下是我的一些建议: 设计正常尺寸屏幕和中等分辨率的app.随着时间的推移,设备有着向更大尺寸,

“全栈2019”Java第四十八章:重写方法Override

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第四十八章:重写方法Override 下一章 "全栈2019"Java第四十九章:重载与重写对比详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组

第四到八章 章节性总结

第四章:汇编源程序 要完成一个程序必须要先编写汇编源文件,然后进行汇编,链接,执行.使用debug调试时,调试的必须是连接后得到的可执行文件,并且要带扩展名.即: debug ××.exe. 第五章 用[0]表示一个内存单元时,0表示单元的偏移地址,段地址默认在ds中,单元的长度(类型)可以由具体指令中的其他操作对象(比如说寄存器)指出.[bx]同样也表示一个内存单元,它的偏移地址在bx中. [BX] mov ax,[bx]  即(ax)=((ds)*16+(bx))             m

第四十八章

第四十八章1 人生的“减法”,你会做吗? 为学者日益,为道者日损 把事情当做学问来研究的人,欲望越来越多,追求道的人,欲望越来越少. 做“减法”是我们需要的人生智慧. 各位亲爱的朋友,我们今天接着来聊<道德经>.今天来到了新的一章,四十八章,各位一定要好好学第四十八章,因为四十八章里的话特别的有用.特别的深刻. 我们先来学头两句,老子说,“为学者日益,为道者日损”,就这两句话,里边道理非常深,我给大家先解释一遍,“为学者日益”就是把事情当做学问来研究的,这些人做事越做越多,学的越学越多,也就是