2010-07-15 94 views
12

我的項目是.NET/WinForms。不允許ListView有零選項

我有一個總是充滿項目的列表視圖。我希望它始終有選擇。但是,如果我點擊列表視圖項下方的空白區域,則會失去選擇。

該列表有多個選擇= true和隱藏選擇= false。

+1

重複:http://stackoverflow.com/questions/2382369/prevent-listview-to-lose-selected-item – Marek 2010-07-15 11:27:10

+1

只有重複的主題。該線程沒有真正的答案。 – 2010-07-15 11:44:20

+1

並且該線程的最高更新答案是WPF,這是WinForms。 – GenericTypeTea 2010-07-15 11:46:21

回答

22

您需要防止本地控件看到鼠標單擊,因此它不會取消選擇某個項目。爲您的項目添加一個新類並粘貼下面顯示的代碼。編譯。將它從工具箱的頂部放到表單上,替換現有的表單。

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); 
    } 
} 
+0

感謝您的建議,但它有點太低級。我想我會按照下面的建議去進行手動設置選擇。 – Alex 2010-07-16 11:35:19

+2

奇怪的是,我認爲「手動設置選擇回來」是一個低級別的黑客攻擊。 – 2010-07-16 12:41:04

+0

這是一個很好的解決方案,但我必須讓它成爲公共課才能使用它。 – Hugoagogo 2013-11-25 03:57:09

0

您需要處理ListView的SelectedIndexChanged事件,並且在發生此事件後沒有選擇項目的情況下,以編程方式重新選擇上次已知的選擇。

0

ListView有一個SelectedIndexChanged事件。聽取它,然後查詢listView.SelectedItems.Count屬性 - 如果它爲零,請選擇第一個/最後一個選定的項目。

2

像其他人所說的那樣,SelectedIndexChanged事件是您應該看的,但您應該將其與ItemSelectionChanged事件配合使用。下面是一些代碼,我剛熟了起來:

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

對於純代碼複用的目的,它可能會是值得的把這個代碼放到一個新的用戶控件和具有決定是否允許一個屬性最後選擇將丟失:

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; 

} 
1

此之後,如果你不需要多選的作品。它具有不需要跟蹤上次選擇哪個項目的優點。

private void ListViewAny_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    if ((sender as ListView).FocusedItem != null) 
    { 
     (sender as ListView).FocusedItem.Selected = true; 
    } 
} 
1
private void LV_MouseUp(object sender, MouseEventArgs e) 
    { 
     if (LV.FocusedItem != null) 
     { 
      if (LV.SelectedItems.Count == 0) 
       LV.FocusedItem.Selected = true; 
     } 
    } 

(無多選)