stringgrid中如何控制输入的有效性(200分)

  • 主题发起人 主题发起人 cuigw
  • 开始时间 开始时间
C

cuigw

Unregistered / Unconfirmed
GUEST, unregistred user!
在stringgrid中,我想实现这样的功能:
1.在焦点离开CELL时,截获此事件
2.在焦点离开CELL时能够验证CELL值的有效性。
 
OnGetEditText事件
Occurs when the in-place editor requests the value of a cell.

type TGetEditEvent = procedure (Sender: TObject; ACol, ARow: Longint; var Value: String) of object;
property OnGetEditText: TGetEditEvent;

Description

Write an OnGetEditText event handler to provide...
 
还可以利用OnSetEditText事件, 如:
procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol,
ARow: Integer; const Value: String);
begin
if Value='sa' then showmessage('invalid')
end;
//Stringgrid的options属性中goEditing, goAlwaysShowEditor为真
 
我也正被此事困扰!
1、OnSetEditText不行,因为只有在输入完后离开时才需判断输入数据的有效性
2、OnGetEditText也不行,因为在用移动键移动后它会响应,但是用鼠标点击其他
CELL时它不会响应!
3、我也曾经用鼠标的事件ONMOUSEDOWN进行补充,结果也不理想。因为在编辑状态下
有时它不会响应如“右键”。而且鼠标点击其他CELL时,原来需要判断的CELL也不
好确定;

如果谁能圆满的解决这个问题,我愿再加¥200

 
想了好多办法都不行,
最后找了一个控件,在32 Bit Delphi上,控件叫ADVCGRID
用上感觉不可以但也有问题。
 
能不用它就不要用它了
 
我建议从TStringGrid里继承出一个新的类,然后添加两个属性用于表示前一个Cell的Col、
Row,然后在OnSelectCell事件里进行验证。
 
to cuigw:
unit MyStringGrid;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Grids;

type

TMyStringGrid = class(TStringGrid)
private
FOnCellEditExit: TNotifyEvent;
protected
function CreateEditor: TInplaceEdit; override;
published
property OnCellEditExit: TNotifyEvent read FOnCellEditExit
write FOnCellEditExit;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Samples', [TMyStringGrid]);
end;

type

TMyInplaceEdit = class(TInplaceEdit)
private
FOnEditExit: TNotifyEvent;
procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
protected
property OnEditExit: TNotifyEvent read FOnEditExit write FOnEditExit;
end;

{ TMyInplaceEdit }
//当 cell 处于编辑状态而将要失去焦点时触发该消息
procedure TMyInplaceEdit.WMKillFocus(var Msg: TWMKillFocus);
begin
if Assigned(FOnEditExit) then
FOnEditExit(Self); //这里可以改成做在失去焦点前你想要完成的处理
inherited; //如果不调用 inherited 则不会失去焦点
end;

{ TMyStringGrid }

function TMyStringGrid.CreateEditor: TInplaceEdit;
begin
Result := TMyInplaceEdit.Create(Self);
TMyInplaceEdit(Result).OnEditExit := FOnCellEditExit;
end;

end.
主要是重载 TInplaceEdit ,我试了可以的。为 StringGrid 加了一个 CellEditExit 事件,
知道了原理,你自己可以作修改。
 
派生一个类,公布一下 InplaceEdit,只要在使用 InplaceEdit 前检验一下是否有效,
就可以得到任何输入内容了,当然处理时机应当是在 OnSelectCell,
判断Row|Col是否已经改变。
 
生成新的组件是个好办法,不过还不能理解的话,可以有个折衷的方法,在cell处,动态产生个combobox
这样可以有combobox.exit的事件了。在cell中加combobox的方法,在这论坛里可以找到。
 
以下是帮助文件的内容:
Occurs when the user edits the value of a cell.

Delphi syntax:

property OnSetEditText: TSetEditEvent;

C++ syntax:

__property TSetEditEvent OnSetEditText = {read=FOnSetEditText, write
=FOnSetEditText};

Description

Write an OnSetEditText event handler to perform any special processing of the text edited by the user in an in-place editor. For example, use the OnSetEditText event to retrieve and store the value of a cell so that it can be displayed in an OnDrawCell event handler. OnSetEditText occurs every time the user changes the text.

OnSetEditText does not occur unless the Options property includes goEditing.
 
可以结合设置适当的 OnGetEditMask

在 OnDrawCell 中对无效数据用红色显示!
 
发现onDrawCell中只能改字体颜色,不可以该整个cell的颜色,不然里面的内容会没有
就是说Canvas.Brush.Color := clinfobk; //不可以
Canvas.FillRect(Rect); //不可以
Canvas.Font.Color:=clred; //可以
Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]); //可以
不知道为什么?

另外,我正用combobox来解决CELL的控制,有相同经历的人希望交流一下。
 
后退
顶部