我目前正在使用winform c#中的listview 每次我点击列表视图上的空白区域, 所选项目丢失。
答案 0 :(得分:9)
listview控件的HideSelection
属性默认为True
。把它变成False
并且你很高兴...在某些情况下这已经足够了。
答案 1 :(得分:2)
我认为有一个属性可以防止这种情况发生,但现在我找不到了。
你可以试试这个:
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListView listView = sender as ListView;
if (listView.SelectedItems.Count == 0)
foreach (object item in e.RemovedItems)
listView.SelectedItems.Add(item);
}
答案 2 :(得分:2)
我完成了这样的事情:
private void lvReads_MouseUp(object sender, MouseEventArgs e)
{
if (lvReads.SelectedItems.Count == 0)
if (lvReads.Items.Count > 0)
lvReads.Items.Find(currentName, false)[0].Selected = true;
}
和
private void lvReads_SelectedIndexChanged(object sender, EventArgs e)
{
if (lvReads.SelectedItems.Count == 1)
{
selectedIndex = lvReads.SelectedIndices[0];
if (currentName != lvReads.Items[selectedIndex].Name)
{
//load item
}
currentName = lvReads.Items[selectedIndex].Name;
}
}
答案 3 :(得分:2)
您必须从ListView类继承并执行一些低级别的消息处理
class ListViewThatKeepsSelection : ListView
{
protected override void WndProc(ref Message m)
{
// Suppress mouse messages that are OUTSIDE of the items area
if (m.Msg >= 0x201 && m.Msg <= 0x209)
{
Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
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);
}
}
答案 4 :(得分:1)
这在WinForms中比在WPF中要难得多。 WinForms有一个SelectedIndexChanged
事件,它不告诉你任何已经选择的内容, plus 每次选择或取消选择行时都会触发它。
因此,如果选择了一行并且您选择了另一行,则会收到两个SelectedIndexChanged
个事件:
问题在于,在事件#1期间,ListView没有选择任何内容,您不知道是否会出现将选择第二行的事件#2。
您可以做的最好的事情是等待应用程序空闲(选择更改后几毫秒),如果列表视图仍未选择任何内容,则放回最后选择的行。
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
ListView lv = (ListView)sender;
if (lv.SelectedIndices.Count == 0)
{
if (!this.appIdleEventScheduled)
{
this.appIdleEventScheduled = true;
this.listViewToMunge = lv;
Application.Idle += new EventHandler(Application_Idle);
}
}
else
this.lastSelectedIndex = lv.SelectedIndices[0];
}
void Application_Idle(object sender, EventArgs e)
{
Application.Idle -= new EventHandler(Application_Idle);
this.appIdleEventScheduled = false;
if (listViewToMunge.SelectedIndices.Count == 0)
listViewToMunge.SelectedIndices.Add(this.lastSelectedIndex);
}
private bool appIdleEventScheduled = false;
private int lastSelectedIndex = -1;
private ListView listViewToMunge;
答案 5 :(得分:0)
我知道十年前问过这个问题。但是我遇到了同样的问题,并立即找到了一个简单而优雅的解决方案,并真诚地希望与大家分享。
有一个代码(在VB.NET中,但是用C#编写它没什么大问题):
Public Class SettingsBox ' Form that contains ListView (lvScreen)
Private nScreenTracer As Integer
Private nSelectedScreen As Integer
Private Sub lvScreen_ItemSelectionChanged(sender As Object,
e As ListViewItemSelectionChangedEventArgs) Handles lvScreen.ItemSelectionChanged
If e.IsSelected Then nScreenTracer = e.Item.Index
End Sub
Private Sub lvScreen_MouseDown(sender As Object,
e As MouseEventArgs) Handles lvScreen.MouseDown
nScreenTracer = -1
End Sub
Private Sub lvScreen_MouseUp(sender As Object,
e As MouseEventArgs) Handles lvScreen.MouseUp
If nScreenTracer = -1 Then
lvScreen.SelectedIndices.Add(nSelectedScreen)
Else
nSelectedScreen = nScreenTracer
End If
End Sub
End Class
此解决方案适用于单项选择,也可以使用List(Of Integer)进行简单的重新设计以进行多选