Отключение отмены выбора в элементе управления 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";
}
}
Выше работает, но есть проблема. При щелчке мышью по пустой области снимается выделение элемента, и стрелка вверх / вниз клавиатуры больше не работает, хотя элемент по-прежнему выглядит выделенным. Если я игнорирую клавиатуру, то при выборе мыши она работает нормально и игнорирует щелчки в пустых областях с сообщением "НЕТ" в строке состояния.
Любые идеи, как это исправить, чтобы он работал со всеми возможными методами выбора (клавиатура, мышь (любой другой?)).
2 ответа
Вот еще один возможный ответ на ваш вопрос:
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.
Перехват 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;