2

TListView (vsIcon) を一種のタブとして使用したいので、タブと同じように 1 つの項目のみを選択できます。項目を 1 つだけ選択しても問題ありません (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";
    }
}

上記は機能しますが、問題があります。空白の領域でマウスをクリックすると、アイテムの選択が解除され、アイテムがまだ選択されているように見えても、キーボードの上下矢印が機能しなくなります。キーボードを無視すると、マウスの選択で正常に機能し、ステータスバーに「いいえ」というメッセージが表示された空白領域のクリックが無視されます。

これを修正して、考えられるすべての選択方法(キーボード、マウス(その他?))で動作するようにする方法についてのアイデア。

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 に答える