我想使用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”消息。
任何想法如何解决这个问题所以它适用于所有可能的选择方法(键盘,鼠标(任何其他?))。
答案 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.