阻止用户选择但允许以编程方式进行选择

时间:2012-11-27 12:09:50

标签: c# winforms listview

我的Windows应用程序中有一个listview控件,其中填充了一些项目。我将通过将ListViewItem.Selected属性设置为true来以编程方式选择项目。但我想阻止用户在列表视图中选择一个项目。即,应始终以编程方式选择它。我可以通过禁用控件来阻止用户选择,但是禁用控件也会禁用不正确的滚动条。

即使我已经创建了一个自定义列表视图控件并使用WndProc check link实现了ItemSelectionChanging事件处理程序,我可以使用它来取消事件,如下所示,

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

但同样,这将取消该事件,即使对于以编程方式选择的项目也是如此。我的问题是,无论如何都要确定选择是手动(由用户)还是以编程方式在SelectedIndexChanged或使用WndProc消息进行。

注意:如果需要,我将上传CustomListView控件的代码。

更新1

感谢emartel。这是一个很好的想法。即使我尝试通过仅在选择项目之前订阅事件并在选择之后立即删除它来实现相同的目的。通过这种方式,在选择时,将立即触发事件并且它将继续。这工作正常。

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

但是我又遇到了一个问题,即如果用户手动选择一个项目,则不会发生任何事情(不会触发任何事件),但会突出显示该项目。一旦项目突出显示,并且如果我尝试以编程方式选择相同的项目,则不会发生任何事件,即SelectedIndexChanged事件未被触发,因为它已经突出显示。

注意:即使我遵循您建议的Flag方法,也会出现相同的行为。

更新2

我可以通过自己的方法解决这个问题,而不是像emartel的建议那样处理事件。但我的问题是,根据我的更新1,当项目突出显示但未实际选择时,是否会触发SelectedIndexChanged事件?

3 个答案:

答案 0 :(得分:1)

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;
    }
}

<强>示例:

enter image description here

答案 1 :(得分:0)

嗯,一个简单的解决方案是保留一个标记,说明你是以编程方式更改选择并允许事件通过,并在完成后重置标志

修改:如果您(并且只有您)可以更改选择,并且您可以通过编程方式执行此操作,那么您可以控制以及何时发生这种情况,为什么会这样做?你甚至需要EventHandler?为什么不调用一个方法来做你想要的任何处理?

答案 2 :(得分:0)

一种方法是保留所选项目的列表,并在每次更改时从代码中刷新选择。

还有一个 ItemSelectionChanged 事件,该事件是针对选择状态已更改的每个项目单独引发的。您可以将选择状态翻转回此事件。

您还可以查看Better ListView Express控件。它具有只读模式,因此用户无法更改选择。它的设置非常简单:

listView.ReadOnly = true;

full version还支持自定义不可选项。只需设置:

listView.Items[0].Selectable = false;

使第一个不可选择(由用户)。

当然,你仍然可以从代码中选择项目。

下图显示了不可选择的项目(它们用灰色标记):

enter image description here