在TListView控件中禁用取消选择

时间:2011-12-26 14:06:17

标签: delphi c++builder tlistview

我想使用TListView(vsIcon)作为一种标签 - 这样只能选择一个项目,就像标签一样。只选择一个项目没有问题(禁用Multiselect属性)。问题是在列表视图中单击图标和文本之间的空白点时取消选择项目。

这是我到目前为止所尝试的内容:

void __fastcall TForm::ListViewChanging(TObject *Sender, TListItem *Item, TItemChange Change, bool &AllowChange)
{
if (Change == ctState)
    {
    TPoint CursorRel = ListView->ScreenToClient(Mouse->CursorPos);
    AllowChange = (ListView->GetItemAt(CursorRel.x, CursorRel.y) != NULL);
    StatusBar->SimpleText = (AllowChange)? "YES" : "NO";
    }
}

上述工作但存在问题。在空白区域单击鼠标时,取消选择该项目,键盘向上/向下箭头不再起作用,尽管该项目仍然看起来已选中。如果我忽略了键盘,对于鼠标选择它可以正常工作并忽略空白区域的点击,状态栏中显示“NO”消息。

任何想法如何解决这个问题所以它适用于所有可能的选择方法(键盘,鼠标(任何其他?))。

2 个答案:

答案 0 :(得分:4)

拦截WM_LBUTTONDOWN发布到控件,如果点击不在某个项目上,则暂停默认处理。控件的子类,或者使用ApplicationEvents组件等。带有插入器类的Delphi代码示例:

type
  TListView = class(comctrls.TListView)
  protected
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
  end;

  TForm1 = class(TForm)
    ListView1: TListView;
  private
    ..

procedure TListView.WMLButtonDown(var Message: TWMLButtonDown);
begin
  if GetItemAt(Message.XPos, Message.YPos) <> nil then
    inherited;
end;

答案 1 :(得分:1)

以下是您问题的另一个可能答案:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ImgList, ComCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    ImageList1: TImageList;
    StatusBar1: TStatusBar;
    procedure ListView1Changing(Sender: TObject; Item: TListItem;
      Change: TItemChange; var AllowChange: Boolean);
    procedure ListView1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ListView1Enter(Sender: TObject);
  private
    FListItem: TListItem;
    procedure SelectedListItemStateSave;
    procedure SelectedListItemStateRestore;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.SelectedListItemStateRestore;
begin
  ListView1.Selected := FListItem;
  ListView1.Selected.Focused := True; // Always focused
end;

procedure TForm1.SelectedListItemStateSave;
begin
  FListItem := ListView1.Selected;
end;

procedure TForm1.ListView1Changing(Sender: TObject; Item: TListItem;
  Change: TItemChange; var AllowChange: Boolean);
begin
  if (Change=ctState) then
    SelectedListItemStateSave;
end;

procedure TForm1.ListView1Enter(Sender: TObject);
begin
  if ListView1.Selected = nil then
  begin
    FListItem :=ListView1.Items[0]; // Initialization
    SelectedListItemStateRestore;
  end;
end;

procedure TForm1.ListView1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ListView1.GetItemAt(X,Y) = nil then
  begin
    SelectedListItemStateRestore;
  end;
end;

end.