DBGrid1 中的(100分)

  • 主题发起人 主题发起人 李宏光
  • 开始时间 开始时间

李宏光

Unregistered / Unconfirmed
GUEST, unregistred user!
求教:
有一个table1 ,在DBGrid1 显示, 问题是如何做到: table1的一个字段
要进行有效性验证,若输入不合要求,光标怎样停留在原处不动?
下面的程序,有效性倒是能检查,可光标不能停留,

type Einvalid =class(Exception);
procedure TForm1.Table1AValidate(Sender: TField);
begin
try
// 比如:不能为123 !
if table1.FieldByName('A').asinteger=123 then
raise Einvalid.Create(' 输入错误 ');
except
on Einvalid do
application.messagebox('输入错误', ' 提示',MB_OK);
end;
end;
 
Hehe, your requirement can be settled down by Visual C++'s DDX/DDV
mechanism, :)
 
我建议的方法比较土:

您也建立一个数据库(in memory), 结构为:
FieldName as String
HWND as integer

store each field's name and its edit window handle,
and you can raise the exception which passes the field
name to catcher.

The catcher can search mem db to locale its editor
window's handler, then let it activated after popup
an error msg, :)

Poor, :)
 
在你的提示错误信息后加上
dbgrid1.Setfocus
就可以啦
 
Why donn't use a field's EditMask? That will restrict the user input
and keep the caret in the dbgrid cell.
 
完全用标准delphi的方法(不用其他控件或api方法)即可实现您所需要的功能.
不过样子不大好看, 显得比较烦琐, 不过我想不出更好的方法了.
您需要跟踪3个Event. TDbGrid里的OnColEnter, OnColExit 和TTable中的
BeforeScroll.具体方法如下
先设几个个全局变量
var
LastEditCol: integer; // 最后edit的col
LastColHasProcessed: boolean = false;
NeedBack: boolean = false; // 是否需要返回这个edit(即不能移动)
LastBookmark: pointer = nil; // 是否返回原来的记录

procedure TForm1.Dbgrid1ColExit(Sender: TObject);
begin
if not LastColHasProcessed then
begin
LastEditCol:=DbGrid1.SelectedIndex;
// if 判断条件合法 then NeedBack:=true;
// else
// NeedBack:=true;
end;
LastColHasProcessed:=false;
end;

procedure TForm1.DbGrid1ColEnter(Sender:TObject);
begin
if NeedBack or Assigned(LastBookmark) then
begin
Showmessage("输入非法");
if Assigned(LastBookmark) then
begin
Table1.GotoBookmark(LastBookmark);
Table1.FreeBookmark(LastBookmark);
LastBookmark:=nil;
end;
DbGrid1.SelectedIndex:=LastEditCell;
DbGrid1.EditorMode:=true;
LastCellHasProcessed:=true;
NeedBack:=false;
end;
end;

procedure TForm1.Table1BeforeScroll(DataSet: TDataSet);
begin
if not NeedBack then
if 判断条件非法 then
LastBookmark:=Table1.GetBookmark
else
else
LastBookmark:=Table1.GetBookmark;
end;

该方法已在Delphi 3下测试通过.
 
你可在dbgrid的oncolexit中加判断,如不满足条件‘abort'即可。
 
hdq的方法好.
不过同时在TTable.BeforeScroll中也要判断, 不然用户还是能移动到下一条记录上.
 
谢谢各位大侠;
hdq 先生的办法好,能解决我的问题。
Huizhang先生:不用 field's EditMask的原因是: 需要先输入数据,
然后根据输入进行计算查询,根据查询再判断输入是否正确,
field's EditMask 大概完不成这个任务,若行,请指教。

咳!没钱了,借此机会再向大侠们请教个问题,还是在同一个DBGrid1中,
Table1 有一个字段,只能取 0,1,2,3 四个值,
输入时,最好是出现一个下拉框,内容是‘第一项‘,‘第二项‘,
‘第三项‘,‘第四项‘,选择了第几项,相应地等于输入了数码几。
最笨的办法是建立一个相关数据库(很笨!)勉强还能做,
难得是:用户用起来不方便,只有用鼠标点一下那个字段下拉框才出现。
方便的办法应是:
若此字段为空,下拉框自动打开,(有内容不能打开),
我做不到,那位大侠能做到,请指教。以前我用access 做程序时
也遇到类似问题,一直没解决。
 
看来只有自己做这个dbgrid了.
我试试看
 
最好是在field的OnSetText事件中写检查程序(如果肯定是外部输入做check,例如
没有对field直接赋值eg:field.AsString:='test'等等)
假如出错则 Abort

对于字段只能取 0,1,2,3 四个值的问题,不太明白您的意思,为什么要另外
建表?我以为field的OnSetText,OnGetText,和dbgrid的Column的PickList
相加,稍写代码即可得

至于下拉框的问题,继承dbgrid,修改CreateEditor这个function,只要将
TDBGridInplaceEdit源代码抄来稍稍加以修改即可,类似问题本人改过好
几次了,非常见效。
 
蓉儿:
若字段为空,下拉框自动打开,(有内容不能打开),这个问题
能否详细说一下?
 
就李红光的第一各问题,不知各位兄弟为何如此费神,
其实只要如此:
1。打开TABLE1的字段编辑器,
选中相应的字段,设置属性:
CustomConstraint:= values> 1 and values <10
ConstraintErrorMessage:= 值必须在[1,10] 之间!!
如果条件是动态的可在程序中给上述属性复值。
 
若字段为空下拉框自动打开(有内容不能打开),这个问题:
需要继承TDBGrid写控件.例如:
TtestDBGrid = class(TDBGrid)
protected
function CreateEditor: TInplaceEdit; override;
end;
implementation
:
:本段抄自dbGrids中有关KillMessage函数那段,
:有关DBGridInplaceEdit,TPopupListbox全部代码(很多,但不要紧,抄来就是)
:
function TtestDBGrid.CreateEditor: TInplaceEdit;
begin
Result := TDBGridInplaceEdit.Create(Self);
end;

其中DBGridInplaceEdit代码里有一段dropdown函数,在这个函数体里
with TCustomDBGrid(Grid) do
Column := Columns[SelectedIndex];
处加一句:
if (not Column.Field.isNull) then exit;
就可以了。
假如各位还想对DBGridInplaceEdit做其他操作,亦可参照此法。

将此秘密公布,还挺舍不得......
诸位有兴趣,去解答一下我发的CacheUpdate问题吧,很急的,拜托!!!
 
你用delphi 4吗?D4 的DBGrid直接支持在某一格的DropDown
 
谢谢各位
 
谢了半天,分数要给谁呢? :)
 
不好意思,我已经发了三次,已经给分了
 
多人接受答案了。
 
后退
顶部