Отключение отмены выбора в элементе управления TListView - PullRequest
2 голосов
/ 26 декабря 2011

Я хотел бы использовать 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";
    }
}

Выше работает, но есть проблема. При щелчке мышью по пустой области снимается выделение элемента, и стрелка вверх / вниз клавиатуры больше не работает, хотя элемент по-прежнему выглядит выделенным. Если я игнорирую клавиатуру, то при выборе мыши она работает нормально и игнорирует щелчки в пустых областях с сообщением «НЕТ» в строке состояния.

Есть идеи, как это исправить, чтобы оно работало со всеми возможными методами выбора (клавиатура, мышь (любая другая?)).

Ответы [ 2 ]

4 голосов
/ 27 декабря 2011

Перехват 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 голос
/ 29 декабря 2011

Вот еще один возможный ответ на ваш вопрос:

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.
...