Jessica Brown
Jessica Brown

Reputation: 8312

Multiselect using mouse in TListview?

Say you have a form with a TListView, with MultiSelect enabled. Normally you have to press shift or control to select multiple items. If I'd like to have the listview select/de-select additional items with only a mouse-click, how do I do that?

Like if you click item1 and then item3 both would be selected, and then if you click item1 again, it would leave only item3 selected.

I don't see any built in properties in the Object Inspector that look relevant. Do I need to modify my ListviewOnMouseDown or ListviewOnSelectItem to change the selection?

Upvotes: 0

Views: 2024

Answers (3)

Sebastian Z
Sebastian Z

Reputation: 4740

Set the ExtendedSelect property of the ListView to False.

Update:
The ListView does not have an ExtendedSelect property. It is only available for the ListBox.

But it would be possible to add that to the ListView. Here's an improved version of the code posted by Sertac that adds ExtendedSelect. I also improved it so it is a bit more user friendly than the original because it keeps the shift key for multi selection working. (I hope I may post that improved version here, it is a bit easier to read than in my comment).

type
  TListView = class(Vcl.ComCtrls.TListView)
  private
    FExtendedSelect: Boolean;
    procedure SetExtendedSelect(const Value: Boolean);
  protected
    procedure WMLButtonDown(var Message: TWMLButtonDown);
      message WM_LBUTTONDOWN;
  public
    property ExtendedSelect: Boolean read FExtendedSelect write SetExtendedSelect;
  end;

procedure TListView.SetExtendedSelect(const Value: Boolean);
begin
  FExtendedSelect := Value;
end;

procedure TListView.WMLButtonDown(var Message: TWMLButtonDown);
begin
  if not FExtendedSelect then
  begin
    if Message.Keys and MK_CONTROL <> 0 then
      Message.Keys := Message.Keys and (not MK_CONTROL)
    else if Message.Keys and MK_SHIFT = 0 then
      Message.Keys := MK_CONTROL;
  end;
  inherited;
end;

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 597971

A ListView does not natively support what you are asking for. You will have to maintain your own list of "selected" items, using the OnClick or OnMouseDown event to detect which item the user is clicking on so you can toggle the contents of your list accordingly and then reset the ListView's selection to match your updated list as needed.

Upvotes: 1

Sertac Akyuz
Sertac Akyuz

Reputation: 54822

This kind of selection is not implemented in listview controls, maybe because they support checkboxes which can be independently checked, I don't know...

You have to modify the behavior yourself. But using OnMouseDown or OnSelectItem events are not really appropriate, as the selection have already been carried out by the time they are fired. Below example intercepts left mouse button down message.

type
  TListView = class(vcl.comctrls.TListView)
  protected
    procedure WMLButtonDown(var Message: TWMLButtonDown);
      message WM_LBUTTONDOWN;
  end;

procedure TListView.WMLButtonDown(var Message: TWMLButtonDown);
begin
  Message.Keys := MK_CONTROL;
  inherited;
end;

You can intercept the message by any other means, assigning to WindowProc, deriving a new control... Of course you can also implement the behavioral change conditionally, or would like to test and preserve other virtual keys/buttons. See documentation in that case.

Upvotes: 2

Related Questions