Delphi DBGrid:如何防止选中行?
我有一个网格的条目,用户将点击多个选择的过程。根据第一个选定行的值,某些条目将无效 我知道DBGrid.SelectedRows.CurrentRowSelected,但我找不到合适的位置来检查我的条件,将其设置为True或False 大概是这样的:Delphi DBGrid:如何防止选中行?,delphi,dbgrid,Delphi,Dbgrid,我有一个网格的条目,用户将点击多个选择的过程。根据第一个选定行的值,某些条目将无效 我知道DBGrid.SelectedRows.CurrentRowSelected,但我找不到合适的位置来检查我的条件,将其设置为True或False 大概是这样的: var bm: TBookmark; CachedIdentity: String; CanSelect: Boolean; begin with dgbSkypeConversations do begin if Se
var
bm: TBookmark;
CachedIdentity: String;
CanSelect: Boolean;
begin
with dgbSkypeConversations do
begin
if SelectedRows.Count > 0 then
begin
DataSource.DataSet.DisableControls;
bm := DataSource.DataSet.GetBookmark;
CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString;
DataSource.DataSet.GotoBookmark(SelectedRows[0]);
CanSelect := DataSource.DataSet.FieldByName('identity').AsString <> CachedIdentity;
DataSource.DataSet.GotoBookmark(bm);
DataSource.DataSet.FreeBookmark(bm);
SelectedRows.CurrentRowSelected := CanSelect;
DataSource.DataSet.EnableControls;
end;
end
end;
var
bm:TBookmark;
CachedIdentity:字符串;
CanSelect:布尔型;
开始
用dgbSkypeConversations做什么
开始
如果选择了rows.Count>0,则
开始
DataSource.DataSet.DisableControls;
bm:=DataSource.DataSet.GetBookmark;
CachedIdentity:=DataSource.DataSet.FieldByName('identity').AsString;
DataSource.DataSet.GotoBookmark(SelectedRows[0]);
CanSelect:=DataSource.DataSet.FieldByName('identity')。关联CachedIdentity;
DataSource.DataSet.GotoBookmark(bm);
DataSource.DataSet.FreeBookmark(bm);
SelectedRows.CurrentRowSelected:=CanSelect;
DataSource.DataSet.EnableControls;
结束;
结束
结束;
我在
Application.OnMessage
和DBGrid以及表单中尝试了OnMouseDown
事件,但是它们不起作用,并且没有TBookmarkList.beforeinseritetem
事件。我可以做什么或必须更改什么?如果查看TCustomDBGrid.MouseDown的源代码,您将看到它如何计算出发生MouseDown事件的数据集行(如果有)。您还将看到导致当前行的选择状态被切换的行:
if ssCtrl in Shift then
CurrentRowSelected := not CurrentRowSelected
记住这一点,为网格设置一个OnMouseUp
事件,并在其中设置一个断点
然后您应该注意到,由于网格的MouseDown
事件中发生了什么,在调用OnMouseUp
事件时,网格数据集的当前行已移动到单击的数据行(请参见下面的注释)。因此,此时您可以检查当前行是否符合允许用户选择它的条件,如果不符合,则取消选择。我认为这回答了您的具体问题“如何防止选中某一行?”
作为一个用户,取消选择行为会让我有点恼火,所以您可能应该给用户一些指示,说明取消选择行的原因
注意:显然,网格的Mousedown
将导致调用数据集的MoveBy
这一事实意味着数据集的OnScroll
事件已被触发。根据您想要执行的具体操作,OnScroll
事件可能是检查当前数据行是否符合您的选择标准的地方,如果不符合,则在那里开始取消选择的过程。在任何情况下,数据集应该已经位于调用DBGrid.MouseDown
事件的datarow上,这一事实应该可以避免在MouseUp
中识别它的麻烦
希望这足够让你走了……我不会把事情弄得这么复杂。
如果比较总是在第一个选择上进行。
我在这里使用的代码具有硬编码值。
不要跳转到书签
// first selection-----------------------------
if DBGrid1.SelectedRows.Count = 1 then begin
CachedIdentity := 'Sonnenbrille'; // Sunglasses
//CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString;
Exit;
end;
做比较
if DBGrid1.SelectedRows.CurrentRowSelected then begin
//if CachedIdentity <> DataSource.DataSet.FieldByName('identity').AsString
if Pos(LookingFor,DBGrid1.DataSource.DataSet.FieldByName('haupttxt').AsString)=0
then DBGrid1.SelectedRows.CurrentRowSelected := False;
ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));
end;
你的q标题似乎与你在q文本中描述的不匹配。您是否试图阻止用户选择网格中的某些行?如果是,为什么不首先阻止它们显示,例如通过在网格数据集上使用过滤器?第一部分:是。第二,因为用户需要查看数据,然后决定选择什么,而不是在。。。我已经做了你能想象到的所有过滤的事情,但是我不能改变用户的要求。当用户做出第一个选择(这是你想要禁用行的点)时,你可以过滤以删除不符合条件的行,从UI的角度看,这要干净得多。虽然你可能会以某种方式阻止用户选择某些行,但在这一点上,你不能以不同的方式绘制它们,以表明它们已被禁用(不可选择)。我已经删除了书签肥胖症。但是DBGRid KeyUP和MouseUP事件是我想要的关键。非常感谢。@JoséEduardo:很高兴我能帮忙:-)
var
CachedIdentity : string;
procedure TForm2.canSelectedV1;
begin
// first selection-----------------------------
if DBGrid1.SelectedRows.Count = 1 then begin
CachedIdentity := 'Sonnenbrille'; // Sunglasses
//CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString;
Exit;
end;
if DBGrid1.SelectedRows.CurrentRowSelected then
begin
//if CachedIdentity <> DataSource.DataSet.FieldByName('identity').AsString
if Pos(LookingFor,DBGrid1.DataSource.DataSet.FieldByName('haupttxt').AsString)=0
then DBGrid1.SelectedRows.CurrentRowSelected := False;
ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));
end;
end;
procedure TForm2.DBGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
canSelectedV1;
end;
procedure TForm2.DBGrid1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
canSelectedV1;
end;
end.