How can I force a ListView to disregard clicking/not highlight a clicked item?
Asked Answered
S

3

8

As I'm not processing the items in a ListView based on what a user may select (the processing always uses everything in the list), I want to disallow the selecting of an item which may make the user think he is limiting the processing to that one item (I've already got multiselect = false, so that's not an issue).

Sticker answered 28/9, 2012 at 21:40 Comment(0)
S
16

There is not any property to disable item selection in the ListView.

What you can do is to handle the event that notifies that an item has been selected by attaching an event handler to ItemSelectionChanged and then deselect the item:

yourListView.ItemSelectionChanged += yourListView_ItemSelectionChanged;

private void yourListView_ItemSelectionChanged(
    object sender,
    ListViewItemSelectionChangedEventArgs e)
{
   if (e.IsSelected)
      e.Item.Selected = false;
}
Servant answered 28/9, 2012 at 21:47 Comment(0)
J
9

To add to Adriano Repettis soloution, I had something similar where I grayed out the items I wanted to block, his solution prevents the blue highlight but the Item still has focus which causes a problem when the item's backcolor is set to anything but white since some of the selected line becomes white. to handle this, I suggest adding the line:

e.Item.Focused = false;

the final code:

yourListView.ItemSelectionChanged += yourListView_ItemSelectionChanged;

private void yourListView_ItemSelectionChanged(
    object sender,
    ListViewItemSelectionChangedEventArgs e)
{
    if (e.Item.BackColor == Color.LightGray)
    {
        e.Item.Selected = false;
        e.Item.Focused = false;
    }
}
Jataka answered 29/2, 2016 at 13:50 Comment(0)
S
1

The solution can cause flicker. You might want to trap mousedown and mouseup events. In mousedown you disable redraw of the listview by either sending WM_SETREDRAW message to the listview with 0 wParam or by calling LockWindowUpdate passing the window handle of the listview. Ex

SendMessage(listview.Handle, WM_SETREDRAW, 0, 0);

Or

LockWindowUpdate(listview.Handle);

In mouseup you will enable redraw by either of the methods below.

SendMessage(listview.Handle, WM_SETREDRAW, 1, 0);

Or

LockWindowUpdate(IntPtr.Zero);

...and, you don't have to invalidate the listview right away. It will do it by itself when necessary.

Take note that you have to do dllimports in this method.

Do you think that's overkill?

Here's another:

extend the ListView class, override WndProc, wait for the WM_NOTIFY to be reflected to the control, check for the first four bytes of the m.LParam if it is -100 and set m.Result = (IntPtr)1 if it is and don't pass the message to base.WndProc.

-100 is LVN_ITEMCHANGING. Returning 1 or 0 via m.Result will disallow or allow the change to take place. The first four bytes of m.LParam is the notification code, the next four bytes the identification of the control sending the message and the 3rd fout bytes is the window handle of the control sending the message. For more information see NMHDR and NMLISTVIEW structures. Google is your friend.

Late answer, though. You might think writing this long took me years to finish.

Starrstarred answered 11/7, 2021 at 18:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.