2010-03-04 27 views
7

Tôi hiện đang làm việc trên một listview trong winform C# và mỗi khi tôi bấm vào một không gian trống trên listview, mục đã chọn bị mất.ngăn chặn listview để mất mục đã chọn

+0

WinForms hoặc WPF? Không gian trống ở bên phải hoặc bên dưới? Bạn muốn điều gì xảy ra? – Grammarian

+0

có thể trùng lặp của [Disallow ListView để có 0 mục đã chọn] (http://stackoverflow.com/questions/3255046/disallow-listview-to-have-zero-selected-items) –

+0

trong thuộc tính ... HideSelection = False và FullRowSelect = True –

Trả lời

2

Tôi nghĩ rằng có một tài sản ngăn chặn điều này xảy ra, nhưng bây giờ tôi không thể tìm thấy nó.

Bạn có thể thử này:

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

Điều này sẽ chỉ hoạt động trong WPF. – Grammarian

+1

@Grammarian - Câu hỏi không chỉ rõ liệu đó là WPF, WinForms, ASP, Silverlight hay bất kỳ thứ gì khác. Tôi chỉ trả lời với cái mà tôi tình cờ đã mở trong IDE lúc này. Bạn nên đăng câu trả lời bằng công nghệ hiển thị C# yêu thích của mình! :-) –

+0

thực sự là quyền của bạn. nó trong winforms – EdgarGad

1

Đây là khó khăn hơn nhiều việc phải làm trong WinForms hơn trong WPF. WinForms có một sự kiện SelectedIndexChanged không cho bạn biết bất cứ điều gì về những gì đã được chọn, cộng với nó được kích hoạt mỗi khi một hàng được chọn hoặc bỏ chọn.

Vì vậy, nếu liên tiếp được chọn và bạn chọn một hàng khác nhau, bạn nhận được hai SelectedIndexChanged sự kiện:

  1. một sau khi hàng đã chọn không được chọn
  2. khác khi hàng mới được chọn.

Vấn đề là, trong sự kiện số 1, ListView không có gì được chọn và bạn không biết liệu sự kiện số 2 sắp đến sẽ chọn hàng thứ hai hay không. Điều tốt nhất bạn có thể làm là đợi cho đến khi ứng dụng của bạn không hoạt động (một vài phần nghìn giây sau khi lựa chọn đã thay đổi), và nếu listview vẫn không có gì được chọn, hãy đặt lại hàng đã chọn cuối cùng.

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

tôi thực hiện nó như thế này:

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

Đây là giải pháp hiệu quả với mã tối thiểu. – hfann

1

Bạn cần phải kế thừa từ lớp ListView và làm một số xử lý thông báo ở mức độ thấp

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

Câu trả lời tương tự ở đây: http://stackoverflow.com/a/3255191/188926 – Dunc

7

Điều khiển danh sách xem có HideSelection thuộc tính mặc định là True. Làm cho nó False và bạn tốt để đi ... trong một số trường hợp này là đủ.

+0

Điều này không giải quyết được vấn đề được đăng, anh ấy không gặp vấn đề gì khi bỏ chọn mục khi mất tiêu điểm. – Hugoagogo

+0

Hiệu chỉnh: anh * đang * có vấn đề với các mục đã bỏ chọn.Các mục đã chọn sẽ không được đánh dấu bởi vì điều khiển mất các mục được chọn. – Suncat2000

Các vấn đề liên quan