2010-03-04 28 views
7

Obecnie pracuję nad listview w winform C# i za każdym razem klikam puste miejsce na liście, wybrany element zostanie utracony.zapobiec wyświetlaniu listy wybranych elementów

+0

WinForms lub WPF? Puste miejsce po prawej lub poniżej? Co chcesz się stać? – Grammarian

+0

możliwy duplikat [Disallow ListView, aby mieć zero wybranych elementów] (http://stackoverflow.com/questions/3255046/disallow-listview-to-have-zero-selected-items) –

+0

we właściwościach ... HideSelection = Fałsz i FullRowSelect = True –

Odpowiedz

2

Myślałem, że istnieje właściwość, która temu zapobiegła, ale teraz nie mogę go znaleźć.

Można spróbować to:

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

To będzie działać tylko w WPF. – Grammarian

+1

@ Gramatyka - pytanie nie określało, czy było to WPF, WinForm, ASP, Silverlight czy cokolwiek innego. Właśnie odpowiedziałem tym, który akurat miałem otwarte w IDE w tej chwili. Powinieneś opublikować odpowiedź w ulubionej technologii wyświetlania C#! :-) –

+0

rzeczywiście twoje prawo. jest w winformach – EdgarGad

1

Jest to o wiele trudniejsze do zrobienia niż w WinForms w WPF. WinForm ma zdarzenie SelectedIndexChanged, które nie mówi nic o tym, co zostało już wybrane, oraz jest uruchamiane za każdym razem, gdy zaznaczono lub odznaczono wiersz.

Więc jeśli zostanie wybrany wiersz i wybrać inny wiersz, otrzymasz dwa SelectedIndexChanged zdarzenia:

  1. jeden po wybrany wiersz jest zaznaczona
  2. inny kiedy zostanie wybrany nowy rząd.

Problem polega na tym, że podczas zdarzenia nr 1 ListView nie ma nic zaznaczonego i nie wiesz, czy nadchodzi zdarzenie # 2, które wybierze drugi wiersz.

Najlepsze, co możesz zrobić, to poczekać, aż aplikacja będzie bezczynna (kilka milisekund po dokonaniu zmiany), a jeśli lista nadal nie ma nic zaznaczonego, odłóż ostatnio wybrany wiersz.

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

osiągnąłem to tak:

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

i

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

To skuteczne rozwiązanie z minimalnym kodem. – hfann

1

Musisz dziedziczyć z klasy ListView i zrobić niskiego poziomu przetwarzania wiadomości

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

Ta sama odpowiedź tutaj: http://stackoverflow.com/a/3255191/188926 – Dunc

7

Kontrolka listview ma wartośćWłaściwośćdomyślnie ustawiona na True. Zrób to, False i dobrze ci idzie ... w niektórych przypadkach to wystarczy.

+0

To nie rozwiązuje problemu z publikacją, nie ma problemu z usunięciem elementów, gdy straci fokus. – Hugoagogo

+0

Korekta: on * ma * problem z usunięciem elementów.Wybrane elementy nie są podświetlane, ponieważ kontrola traci wybrane pozycje. – Suncat2000

Powiązane problemy