Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi DBGrid:如何防止选中行?_Delphi_Dbgrid - Fatal编程技术网

Delphi DBGrid:如何防止选中行?

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

我有一个网格的条目,用户将点击多个选择的过程。根据第一个选定行的值,某些条目将无效

我知道DBGrid.SelectedRows.CurrentRowSelected,但我找不到合适的位置来检查我的条件,将其设置为True或False

大概是这样的:

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.