Difference between revisions of "DialogForm Validation(对话框及表单的确认)"
(Blanked the page) |
|||
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部分中文译文]] |
Revision as of 02:05, 5 July 2015
(以下内容,译自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...
- Visual Prolog 7.2 version.
- Visual Prolog 7.1 version.
有效性确认的概念
有效性确认的概念基础思想是:“控件值应该是有效的”。有效性的确认发生在对话框或表单中按动OK按钮时,但确认工作也可以由程序安排。
控件负责声明自己的内容是有效的,因此,可以对控件设置有效性确认响应器。
对话框或表单作有效性确认时,是逐个控件依次进行的,但如果结果导致
contentsInvalid(Source, FocusControl, ErrorMessage)
则确认工作就终止了。
integerControl和realControl中的有效性确认
我们来创建一个表单,并用类integerControl和realControl加入两个 custom controls (用户控件)。可以在提供的示例工程integerControlAndRealControl看到相应的表单结果。
示例生成的代码如下:
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),
还需要加上对 integerControlAndRealControl 表单的调用:
predicates onFileIntegercontrolRealcontrol : window::menuItemListener. clauses onFileIntegercontrolRealcontrol(Source, _MenuTag) :- Form = integerControlAndRealControl::new(Source), Form:show().
运行这个工程,如果输入了非整数值,将会看到一个说明错误的消息框。
我们也可以加入 onOK 响应器来获取确认后的值:
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").
要注意,如果有效性确认不成功,是不会调用 onOK 响应器的,而且该响应器的调用是发生在所有确认谓词之后。
我们来看一下源文件 \pfc\gui\controls\integerControl.pro ,看看有效性确认是如何实现的。
clauses new() :- editControl::new(), addValidateResponder(onIntValidate). predicates onIntValidate : validateResponder. clauses onIntValidate(_) = contentsInvalid(This,This, ErrorMessage) :- string(ErrorMessage) = checkContent(getText()), !. onIntValidate(_) = contentsOk.
也就是说,如果局部谓词checkContent认为文本内容是 integer 则确认成功。
上面我们说过,确认工作也可以强制程序安排进行。可以这样加一个按钮 TryValidation 及相应的代码:
predicates onTryValidation : button::clickResponder. clauses onTryValidation(_Source) = button::defaultAction() :- tryValidateWithErrorDialog(), !, stdIO::write("All controls are valid\n"). onTryValidation(_Source) = button::defaultAction().
容器控件中的有效性确认
考查容器控件中的有效性确认,我们先来创建一个这样的控件:在工程中创建一个新的控件fromTo,再在其中加入两个integerControl控件。
考虑到只有当From的值小于To的值控件fromTo才是有效的,因此可以这样设置fromTo控件的有效性确认响应器:
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.
请注意,如果有效性确认不成功,控件 from_ctl 会得到焦点。
常用控件的有效性确认
我们在工程中创建一个新控件 myControl ,再创建一个表单并在其中添加三个控件:
- edit 控件;
- listbox 控件;
- myControl 类的用户控件。
可以在提供的示例usualControls中看到表单的结果。
初始化代码中包含了响应器的设置及对三个控件的初始化内容:
clauses new(Parent) :- formWindow::new(Parent), generatedInitialize(), edit_ctl:addValidateResponder(validateEditCtl), listbox_ctl:addList(["First","Second","Third"]), listbox_ctl:addValidateResponder(validateListBox).
有效性确认响应器是这样的:
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().
可以看到,对控件的有效性确认可以有各种不同的方法。