|
|
Line 1: |
Line 1: |
| (以下内容,译自[[:Category:Tutorials]]中的DialogForm Validation。更多内容可以参看[[:Category:Tutorials部分中文译文]]及[[:Category:Chinese]]。)
| |
|
| |
|
|
| |
| 用户按了对话框中的OK按钮后,就意味着将要出现某件事情。不过只有对话框或表单中的数据有效时,事情才会出现。对话框和表单必须经过 '''有效性确认'''。本专题将描述由PFC GUI支持的有效性确认机制,还要介绍如何使用校验控件''integerControl'' 和 ''realControl'' 及如何确认对话框表单中其它的控件。
| |
|
| |
| 本文将演示如何确认在对话框或表单中的控件。首先,要介绍有效性确认的概念。我们会看到integerControl和realControl是如何使用有效性确认概念的。接着,我们要考虑在容器控件中的有效性确认问题。最后,来看几个常用控件的有效性确认,这些控件有:editControl、listBox、新建用户控件。
| |
|
| |
| '''下载''' 本文使用的示例工程源文件:
| |
|
| |
| * Visual Prolog 7.4 和 7.3 IDE下安装示例:
| |
| *:'''Help -> Install Examples...'''
| |
| * [http://download.pdc.dk/vip/72/tutorial_examples/validation.zip Visual Prolog 7.2 version].
| |
| * [http://download.pdc.dk/vip/71/examples/tutorial_examples/validation.zip Visual Prolog 7.1 version].
| |
|
| |
|
| |
| ==有效性确认的概念==
| |
|
| |
| 有效性确认的概念基础思想是:“控件值应该是有效的”。有效性的确认发生在对话框或表单中按动OK按钮时,但确认工作也可以由程序安排。
| |
|
| |
| 控件负责声明自己的内容是有效的,因此,可以对控件设置有效性确认响应器。
| |
|
| |
| 对话框或表单作有效性确认时,是逐个控件依次进行的,但如果结果导致
| |
|
| |
| <vip>contentsInvalid(Source, FocusControl, ErrorMessage)</vip>
| |
|
| |
| 则确认工作就终止了。
| |
|
| |
| ==integerControl和realControl中的有效性确认==
| |
|
| |
| 我们来创建一个表单,并用类integerControl和realControl加入两个 '''custom controls''' (用户控件)。可以在提供的示例工程<vp>integerControlAndRealControl</vp>看到相应的表单结果。
| |
|
| |
| 示例生成的代码如下:
| |
|
| |
| <vip>integerControl_ctl := integercontrol::new(This),
| |
| integerControl_ctl:setPosition(92, 4),
| |
| integerControl_ctl:setSize(60,12),
| |
| realControl_ctl := realcontrol::new(This),
| |
| realControl_ctl:setPosition(92, 20),
| |
| realControl_ctl:setSize(60,12),</vip>
| |
|
| |
| 还需要加上对 <vp>integerControlAndRealControl</vp> 表单的调用:
| |
|
| |
| <vip>predicates
| |
| onFileIntegercontrolRealcontrol : window::menuItemListener.
| |
| clauses
| |
| onFileIntegercontrolRealcontrol(Source, _MenuTag) :-
| |
| Form = integerControlAndRealControl::new(Source),
| |
| Form:show().</vip>
| |
|
| |
| 运行这个工程,如果输入了非整数值,将会看到一个说明错误的消息框。
| |
|
| |
| 我们也可以加入 <vp>onOK</vp> 响应器来获取确认后的值:
| |
|
| |
| <vip>predicates
| |
| onOk : button::clickResponder.
| |
| clauses
| |
| onOk(_) = button::defaultAction() :-
| |
| Integer = integerControl_ctl:getInteger(),
| |
| Real = realControl_ctl:getReal(),
| |
| stdIO::write("Integer value = ",Integer, "\n"),
| |
| stdIO::write("Real value = ",Real, "\n").</vip>
| |
|
| |
| 要注意,如果有效性确认不成功,是'''不会'''调用 <vp>onOK</vp> 响应器的,而且该响应器的调用是发生在所有确认谓词之后。
| |
|
| |
| 我们来看一下源文件 '''\pfc\gui\controls\integerControl.pro''' ,看看有效性确认是如何实现的。
| |
|
| |
| <vip>clauses
| |
| new() :-
| |
| editControl::new(),
| |
| addValidateResponder(onIntValidate).
| |
|
| |
| predicates
| |
| onIntValidate : validateResponder.
| |
| clauses
| |
| onIntValidate(_) = contentsInvalid(This,This, ErrorMessage) :-
| |
| string(ErrorMessage) = checkContent(getText()),
| |
| !.
| |
| onIntValidate(_) = contentsOk.</vip>
| |
|
| |
| 也就是说,如果局部谓词checkContent认为文本内容是 <vp>integer</vp> 则确认成功。
| |
|
| |
| 上面我们说过,确认工作也可以强制程序安排进行。可以这样加一个按钮 TryValidation 及相应的代码:
| |
|
| |
| <vip>predicates
| |
| onTryValidation : button::clickResponder.
| |
| clauses
| |
| onTryValidation(_Source) = button::defaultAction() :-
| |
| tryValidateWithErrorDialog(),
| |
| !,
| |
| stdIO::write("All controls are valid\n").
| |
| onTryValidation(_Source) = button::defaultAction().</vip>
| |
|
| |
| ==容器控件中的有效性确认==
| |
|
| |
| 考查容器控件中的有效性确认,我们先来创建一个这样的控件:在工程中创建一个新的控件<vp>fromTo</vp>,再在其中加入两个integerControl控件。
| |
|
| |
| 考虑到只有当<vp>From</vp>的值小于<vp>To</vp>的值控件<vp>fromTo</vp>才是有效的,因此可以这样设置<vp>fromTo</vp>控件的有效性确认响应器:
| |
|
| |
| <vip>predicates
| |
| validateFromTo : control::validateResponder.
| |
| clauses
| |
| validateFromTo (Source) = control::contentsInvalid(Source,from_ctl,
| |
| "From value must be less than To value") :-
| |
| from_ctl:getInteger() >= to_ctl:getInteger(),
| |
| !.
| |
| validateFromTo (_) = control::contentsOk.</vip>
| |
|
| |
| 请注意,如果有效性确认不成功,控件 <vp>from_ctl</vp> 会得到焦点。
| |
|
| |
| ==常用控件的有效性确认==
| |
|
| |
| 我们在工程中创建一个新控件 <vp>myControl</vp> ,再创建一个表单并在其中添加三个控件:
| |
|
| |
| *edit 控件;
| |
|
| |
| *listbox 控件;
| |
|
| |
| *<vp>myControl</vp> 类的用户控件。
| |
|
| |
| 可以在提供的示例''usualControls''中看到表单的结果。
| |
|
| |
| 初始化代码中包含了响应器的设置及对三个控件的初始化内容:
| |
|
| |
| <vip>clauses
| |
| new(Parent) :-
| |
| formWindow::new(Parent),
| |
| generatedInitialize(),
| |
| edit_ctl:addValidateResponder(validateEditCtl),
| |
| listbox_ctl:addList(["First","Second","Third"]),
| |
| listbox_ctl:addValidateResponder(validateListBox).</vip>
| |
|
| |
| 有效性确认响应器是这样的:
| |
|
| |
| <vip>predicates
| |
| validateEditCtl : control::validateResponder.
| |
| clauses
| |
| validateEditCtl(_) = control::contentsOk :-
| |
| "OK" = edit_ctl:getText(),
| |
| !.
| |
| validateEditCtl(Source) = control::contentsInvalid(
| |
| Source, Source,
| |
| "Edit control expects to have the text 'OK'").
| |
|
| |
| predicates
| |
| validateListBox : control::validateResponder.
| |
| clauses
| |
| validateListBox(Source) = control::contentsInvalid(
| |
| Source,Source,
| |
| "Selection of the first row is not allowed") :-
| |
| 0 = listbox_ctl:tryGetSelectedIndex(),
| |
| !.
| |
| validateListBox(_) = control::contentsOk().
| |
|
| |
| predicates
| |
| validateMyControl : control::validateResponder.
| |
| clauses
| |
| validateMyControl(Source) = control::contentsInvalid(
| |
| Source,Source,
| |
| string::concat("A marker in the ",Missed,
| |
| " part is mandatory")) :-
| |
| Missed = toString(isMandatoryMarkNotActive(
| |
| mandatoryMark, activatedMark)),
| |
| !.
| |
| validateMyControl(_) = control::contentsOk().</vip>
| |
|
| |
| 可以看到,对控件的有效性确认可以有各种不同的方法。
| |
|
| |
| ==参考==
| |
|
| |
| [[Category:Tutorials]]
| |
| [[Category:GUI]]
| |
|
| |
| [[:Category:Tutorials部分中文译文]]
| |