My project is .NET/WinForms.
I have a list view which is always filled with items. I would like it to have selection always. However, if I click on an empty area below list view items, it looses selection.
The list has multiple selection = true and hide selection = false.
This following works if you do not need multiselect. It has the advantage of not needing to to track which item was last selected.
private void ListViewAny_SelectedIndexChanged(object sender, EventArgs e)
{
if ((sender as ListView).FocusedItem != null)
{
(sender as ListView).FocusedItem.Selected = true;
}
}
You need to prevent the native control from seeing the mouse click so it won't unselect an item. Add a new class to your project and paste the code shown below. Compile. Drop it from the top of the toolbox onto your form, replacing the existing one.
using System;
using System.Drawing;
using System.Windows.Forms;
class MyListView : ListView {
protected override void WndProc(ref Message m) {
// Swallow mouse messages that are not in the client area
if (m.Msg >= 0x201 && m.Msg <= 0x209) {
Point pos = new Point(m.LParam.ToInt32());
var hit = this.HitTest(pos);
switch (hit.Location) {
case ListViewHitTestLocations.AboveClientArea :
case ListViewHitTestLocations.BelowClientArea :
case ListViewHitTestLocations.LeftOfClientArea :
case ListViewHitTestLocations.RightOfClientArea :
case ListViewHitTestLocations.None :
return;
}
}
base.WndProc(ref m);
}
}
Like the others have said, the SelectedIndexChanged
event is what you should look at, however you should use it in collaboration with the ItemSelectionChanged
event. Here's some code I've just cooked up:
// Holds the last selected index
private int _previousIndex = -1;
// Restores the previous selection if there are no selections
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.SelectedIndices.Count == 0)
{
if (_previousIndex >= 0)
{
listView1.SelectedIndices.Add(_previousIndex);
}
}
}
// Records the last selected index
private void listView1_ItemSelectionChanged(object sender,
ListViewItemSelectionChangedEventArgs e)
{
if (e.IsSelected)
{
_previousIndex = e.ItemIndex;
}
}
For pure code re-use purposes, it'd probably be worthwhile putting this code into a new UserControl and have a property that determines whether or not to allow the last selection to be lost:
public class CustomListView : ListView
{
protected CustomListView()
{
this.SelectedIndexChanged += new EventHandler(CustomListView_SelectedIndexChanged);
this.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(CustomListView_ItemSelectionChanged);
}
void CustomListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.MaintainLastSelection && this.SelectedIndices.Count == 0)
{
if (_previousIndex >= 0)
{
this.SelectedIndices.Add(_previousIndex);
}
}
}
void CustomListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (e.IsSelected)
{
_previousIndex = e.ItemIndex;
}
}
private int _previousIndex = -1;
public bool MaintainLastSelection
{
get { return _maintainLastSelection; }
set { _maintainLastSelection = value; }
}
private bool _maintainLastSelection;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With