2

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

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

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”消息的空白区域的点击。

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

4

2 回答 2

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;
于 2011-12-26T22:05:07.993 回答
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.
于 2011-12-29T06:42:32.740 回答