Reuben
Reuben

Reputation: 268

Preventing user selection but allowing selection programmatically

I have a listview control in my windows application, which is populated with some set of items. I will make the selection of an item programmatically by setting ListViewItem.Selected property to true. But I want to prevent the user from selecting an item in the listview. i.e., it should be always selected programmatically. I can prevent the user selection by disabling the control, but disabling the control will also disable the scroll bars which is not correct.

Even I have created a custom listview control and implemented a ItemSelectionChanging eventhandler using WndProc check link, using which i can cancel the event as shown below,

private void lstLiveTables_ItemSelectionChanging(object sender, ListViewExItemSelectionChangingEventArgs e)
{
    e.Cancel = true;
}

But again, this will cancel the event, even for an item selected programmatically. My question, is there anyway to identify whether the selection is made manually (by user) or programmatically in SelectedIndexChanged or using WndProc Message.

Note: If it is required, I will upload the code of CustomListView control.

Update 1

Thanks emartel. It was a good thought. Even I tried to achieve the same thing by subscribing to the event only before selecting the item and removed it immediately after selecting. By this way, upon selection the event will be immediately triggered and it will continue. This is working fine.

this.lstTables.SelectedIndexChanged += new System.EventHandler(this.lstTables_SelectedIndexChanged);
item.Selected = true;
this.lstTables.SelectedIndexChanged -= new System.EventHandler(this.lstTables_SelectedIndexChanged);

But again I have a problem that, if the user selects an item manually, nothing will happen (no event will be triggered) but the item alone will be highlighted. Once an item is highlighted and if i try to select the same item programmatically nothing is happening i.e., the SelectedIndexChanged event is not getting triggered for that item as it is already highlighted.

Note: Same behavior even if I follow the Flag approach suggested by you.

Update 2

I can solve this issue by having my own method instead of handling through events as emartel's suggestion. But my question is, according to my update 1, is there anyway to trigger the SelectedIndexChanged event when the item is highlighted but not actually selected?

Upvotes: 2

Views: 1556

Answers (3)

Vinicius Gonçalves
Vinicius Gonçalves

Reputation: 2724

public FrmTest()
{
    list.ItemSelectionChanged += list_ItemSelectionChanged;
}

private bool changing;

private void list_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
    if (changing)
        return;

    if (e.Item == nonSelectableListItem) 
    {
        changing = true;
        nonSelectableListItem.Selected = false;
        changing = false;
    }
}

Sample:

enter image description here

Upvotes: 1

Libor
Libor

Reputation: 3303

One dirty way to do that is to keep list of selected items and refresh selection every time it changes other way than from your code.

There is also an ItemSelectionChanged event which is raised separately for every item whose selection state have changed. You can probably flip the selection state back it this event.

You may also take a look on Better ListView Express control. It have a read-only mode, so that user cannot change the selection. Its setup is very simple:

listView.ReadOnly = true;

The full version also supports custom non-selectable items. Simply setting:

listView.Items[0].Selectable = false;

make the first non-selectable (by the user).

You can still select items from code, of course.

The following image shows non-selectable items in action (they are marked by gray color):

enter image description here

Upvotes: 0

emartel
emartel

Reputation: 7773

Well, an easy solution would be to keep a flag saying that you are programmatically changing the selection and to allow the event to pass, and reset the flag when you're done

Edit: if you, and only you, can change the selection, and you do this programmatically, so you have control over where and when this happens, why do you even need the EventHandler? Why not call a method to do whatever processing you want to happen?

Upvotes: 0

Related Questions