【问题标题】:DBGrid: how to prevent a row from being selected?DBGrid:如何防止一行被选中?
【发布时间】:2016-04-19 16:40:59
【问题描述】:

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

我知道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;

我已经在Application.OnMessage 以及 DBGrid 和 Form 中尝试了 OnMouseDown 事件,但它们不起作用,并且没有 TBookmarkList.BeforeInsertItem 事件。我可以做什么或必须改变什么?

【问题讨论】:

  • 您的 q 标题似乎与您在 q 文本中描述的内容不符。您是否试图阻止用户选择网格中的某些行?如果是这样,为什么不首先阻止它们显示,例如通过在网格的数据集上使用过滤器?
  • 第一部分:是的。其次,因为用户需要查看数据然后决定选择什么,而不是之前...我已经完成了您可以想象的所有过滤器,但我无法更改用户要求
  • 一旦用户进行了第一次选择(这是您要禁用行的点),您可以过滤以删除不符合条件的行,这样更简洁从用户界面的角度来看。虽然您可能会以某种方式阻止用户选择某些行,但此时您不能以不同的方式绘制它们以表明它们已被禁用(不可选择)。

标签: delphi dbgrid


【解决方案1】:

如果您查看TCustomDBGrid.MouseDown 的源代码,您将了解它是如何确定 Mousedown 事件发生在哪个数据集行(如果有)上的。您还将看到导致当前行的选择状态被切换的行:

  if ssCtrl in Shift then
    CurrentRowSelected := not CurrentRowSelected

考虑到这一点,为您的网格设置一个OnMouseUp 事件并在其中放置一个断点。

然后您应该注意到,由于网格的 MouseDown 事件中发生的事情,当您的 OnMouseUp 事件被调用时,网格数据集的当前行已移动到单击的数据行(请参阅下面的注释) .因此,此时您可以检查当前行是否符合您希望允许用户选择它的条件,如果不符合则取消选择它。我认为这回答了您的具体“如何防止选择一行?”

作为用户,取消选择的行为会让我有些恼火,因此您可能应该向用户说明为什么该行已被取消选择。

注意:显然,网格的Mousedown 将导致调用数据集的MoveBy,这意味着数据集的OnScroll 事件已被触发。根据您想要做什么,OnScroll 事件可能是检查当前数据行是否符合您的选择标准的地方,如果不符合您的选择标准,则在此处开始取消选择它的过程。在任何情况下,数据集应该已经在调用DBGrid.MouseDown 事件的数据行上这一事实应该可以省去在MouseUp 中识别它的麻烦。

希望这足以让你继续前进......

【讨论】:

    【解决方案2】:

    我不会把它弄得这么复杂。
    如果比较总是在第一个选择上进行。
    我在这里使用的代码具有硬编码的值。
    无需跳转到书签。

    // 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;
    

    我们可以看到两个被选中了所以
    ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));

    显示2

    现在我们要选择线

    SPORTLICH,优雅的 GUCCI SONNENBRILLE

    我们知道一个简单的 Pos() Sonnenbrille 来查找 SONNENBRILLE Pos() 将 = 0,因此不会进行选择。

    ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));

    也显示2

    代码:

    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.
    

    【讨论】:

    • 我已经削减了书签的胖度。但是 DBGRid KeyUP 和 MouseUP 事件是我想要的关键。非常感谢。
    • @JoséEduardo:很高兴我能帮上忙 :-)
    猜你喜欢
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    相关资源
    最近更新 更多