[.NET/WinForms] Unexpected behavior bij een Listbox

Pagina: 1
Acties:

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:54
Ik heb een vreemd probleem in m'n C#/WinForms applicatie.

Ik heb een ListBox, met daarnaast 2 knoppen waarmee ik Items in die ListBox naar boven of naar onder kan verplaatsen.

De code om een Item naar boven te verplaatsen ziet er als volgt uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void MoveUp(ListBox aListBox)
{
    ListBoxItem             dummy;
    int                     iIndex;
      
    // Move up is only possibly when this is not the first item
    iIndex = aListBox.SelectedIndex;
          
    if( iIndex > 0 )
    {
        dummy                      = (ListBoxItem)aListBox.Items[iIndex - 1];
        aListBox.Items[iIndex - 1] = aListBox.SelectedItem;
        aListBox.Items[iIndex]     = dummy;
        aListBox.SelectedIndex     = iIndex - 1;
    }
          
}


De code om een item naar beneden te verplaatsen is deze:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void MoveDown(ListBox aListBox)
{
    ListBoxItem             dummy;
    int                     iIndex;
          
    iIndex = aListBox.SelectedIndex;
       
    if( iIndex < aListBox.Items.Count - 1 )
    {
        dummy                 = (ListBoxItem)aListBox.Items[iIndex + 1];
        aListBox.Items[iIndex + 1] = aListBox.SelectedItem;
        aListBox.Items[iIndex] = dummy;
        aListBox.SelectedIndex = iIndex + 1;
    }
}


Nu, allemaal goed en wel wat is het probleem nu?
Het MoveUp'en gaat goed. Ik selecteer een item, en klik op MoveUp; het item wordt
naar boven verschoven, en dat item blijft het geselecteerde item zodat ik kan blijven
MoveUppen tot dat dat item het bovenste is.

Als ik een item 'MoveDown', dan lukt het in eerste instantie ook. Het geselecteerde
item wordt naar beneden verplaatst, en dat item is het geselecteerde. Althans, het is zichtbaar
het geselecteerde.
Wanneer ik een tweede keer 'move down' doe, dan wordt niet het item dat zichtbaar geselecteerd is
naar beneden gemoved, maar het item dat erboven staat.
Het is dus zo, dat ik die selectedIndex wel op een nieuwe waarde zet, maar als ik debug en ik ga
kijken wat die selectedIndex is als ik de tweede keer MoveDown doe, dan blijkt dat SelectedIndex
opnieuw de oude waarde heeft. :?
Zeer vreemd, zeker als je weet dat het 'MoveUp'en' totaal geen probleem is.

Iemand bekend met dit fenomeen? Ik kan niet direct een fout in m'n code zien.

https://fgheysels.github.io/


  • dotcode
  • Registratie: Augustus 2003
  • Laatst online: 14-08 11:19

dotcode

///\00/\\

Je code lijkt goed, probeer het eens zo:

Als ik snel kijk lijkt me het logisch als dat je:

aListBox.SelectedIndex = iIndex + 1;

Niet zou hoeven doen, test zonder omdat het geselcteerd zijn iets is dat aan een listitem hangt.

Kijk even of het werk zonder...

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:54
Nope, zonder het setten van die SelectedIndex werkt het niet. Daarom heb ik het er ook expliciet instaan.

Het rare is ook dat, als ik op de Move Up knop klik, en er is geen Item geselecteerd, er gewoon niets gebeurd (zoals het hoort dus). Doe ik een movedown zonder dat er iets geselecteerd is, krijg ik een error.

Ok, dat is logisch. :+ (Zie m'n if statement. Als er niets geselecteerd is, is m'n SelectedIndex -1 natuurlijk). :+
Ff verder debuggen.

[ Voor 16% gewijzigd door whoami op 04-09-2003 15:50 ]

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:54
't Is opgelost.

Ik heb in m'n code voor het move-downen volgende regel gezet voor ik m'n SelectedIndex zet:
code:
1
aListBox.ClearSelected();


Vreemd dat dat nodig is, terwijl dat bij het move-up niet nodig is.

https://fgheysels.github.io/


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

Is het een multiple-selection listbox, toevallig?

Ff wat gestoeid: ListBoxItem wil 'ie bij mij niet kennen, dus "object" van gemaakt (welke reference heb je voor ListBoxItem nodig?). De cast voor de assignment van "dummy" lijkt me overbodig en haal ik weg.

En dan werkt het perfect... :)

offtopic:
De range checks kunnen er ook uit, want je schrijft natuurlijk een handlertje voor SelectedIndexChanged die de knoppen uitzet als de index respectievelijk 0 of Count is :)

[ Voor 6% gewijzigd door Rataplan op 04-09-2003 16:18 ]


Journalism is printing what someone else does not want printed; everything else is public relations.


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:54
Rataplan schreef op 04 September 2003 @ 16:17:
Is het een multiple-selection listbox, toevallig?
Yep.
Ff wat gestoeid: ListBoxItem wil 'ie bij mij niet kennen, dus "object" van gemaakt (welke reference heb je voor ListBoxItem nodig?).
Geen. :+ 't Is een eigen class, met een data-item en een text-item, zodat ik naast het 'zichtbare' item, ook nog een onzichtbaar data-item kan meegeven.

https://fgheysels.github.io/


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

Dat lijkt me het antwoord op je vraag:
quote: SelectedIndex
If the SelectionMode property of the ListBox is set to either SelectionMode.MultiSimple or SelectionMode.MultiExtended (which indicates a multiple-selection ListBox) and multiple items are selected in the list, this property can return the index to any selected item.
Hetzelfde staat bij SelectedItem, die dus blijkbaar niet hetzelfde item hoeft te referencen als SelectedIndex. Het fijne snap ik er ook niet van, maar daar zal je probleem ergens inzitten. Gok ik.
Geen. :+
Klier ;)


Journalism is printing what someone else does not want printed; everything else is public relations.


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:54
Rataplan schreef op 04 september 2003 @ 16:29:
[...]
Dat lijkt me het antwoord op je vraag:
[...]
Hetzelfde staat bij SelectedItem, die dus blijkbaar niet hetzelfde item hoeft te referencen als SelectedIndex. Het fijne snap ik er ook niet van, maar daar zal je probleem ergens inzitten. Gok ik.
Het zal daar idd wel mee te maken hebben, maar ik verwacht toch dat, als ik dit schrijf:
code:
1
aListBox.SelectedIndex = 3;

dat die selectedIndex dan overschreven wordt, en dat het 4de item in m'n listbox het geselecteerde wordt.
En zichtbaar is dat ook zo, het 4de item is geselecteerd, maar als ik dan de SelectedIndex uitlees, dan kreeg ik een andere waarde. Als er meerdere items geselecteerd zijn daardoor, dan zou dat ook zichtbaar moeten zijn.
Klier ;)
Moet je een note? :+

https://fgheysels.github.io/


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

Tja. Prutsen met verwachtingspatronen heeft mij al heel wat uurtjes gekost :D Vooral dat "any" in de help en het feit dat er maar 1 SelectedIndex zou moeten zijn, terwijl er meer SelectedIndex's moeten kunnen zijn brengt mij er met dit soort dingen toe altijd eerst een beetje proof-of-concept te gaan kloppen :) Wat dat betreft helpt je custom ListBoxItem ook niet echt, of die de selectie-eigenschappen goed inherit is natuurlijk lastig te beoordelen, hiervandaan. En nogmaals, zonder cast en met het object-type werkt je code hier perfect!

edit:
Maar dat is met SelectionMode.One :'(
Ik had net met SelectionMode.MultiSimple items drie en vier geselecteerd, terwijl items 1 en 2 van plaats bleven verwisselen >:)
Ach - moeten is zo'n groot woord 8) zolang je d'r maar wat aardigs inzet :>

[ Voor 17% gewijzigd door Rataplan op 04-09-2003 16:57 ]


Journalism is printing what someone else does not want printed; everything else is public relations.


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:54
Rataplan schreef op 04 September 2003 @ 16:50:
custom ListBoxItem ook niet echt, of die de selectie-eigenschappen goed inherit is natuurlijk lastig te beoordelen, hiervandaan.
M'n Custom ListBoxItem class is niets meer of minder dan een class met 2 members. Ze ziet er zo ongeveer uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ListBoxItem
{
  private object _data;
  private string  _text;

  /* Hier komen de properties voor _data en _text */
  
  public ListBoxItem()
  {
  }

  public ListBoxItem( object data, string text)
  {
      ....
  }

  public override string ToString()
  {
      return _text;
  }
}


Ik gebruik die class dus gewoon zodat ik , naast het zichtbare gedeelte in m'n ListBox ook nog een extra-info object kan bewaren per ListItem.
(Vergelijk het een beetje met de Data (of was het nu weer de Tag) property in een ListViewItem.
En nogmaals, zonder cast en met het object-type werkt je code hier perfect!
Mja, nu je het zegt. Om gewoon die items te verwisselen zal ik niet echt die cast nodig hebben. Ik zal het ff uitproberen.
edit:
Maar dat is met SelectionMode.One :'(
Ik had net met SelectionMode.MultiSimple items drie en vier geselecteerd, terwijl items 1 en 2 van plaats bleven verwisselen >:)
Dus toch niet dan. :)

https://fgheysels.github.io/


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

Ik heb d'r nog even mee zitten spelen, en het lijkt erop dat het schrijven van SelectedIndex in MultiSimple niet de juiste events laat afgaan (duh :)). Aangezien SelectedIndex een onbepaalde waarde heeft, is dat niet erg :)

Ik heb het grofweg werkend gekregen door in plaats van een assignment op SelectedIndex de volgende regel te gebruiken:
C#:
1
aListBox.SetSelected(iIndex + 1, true);

't Is iig wat netter dan die ClearSelected, al blijft de vraag hoe dit met een multiple select zou horen te werken :P


Journalism is printing what someone else does not want printed; everything else is public relations.


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:54
Het is zo, dat het nieuwe item gewoon toegevoegd wordt bij de SelectedItems. Ik heb er hier net nog ff mee zitten spelen, en het was zo dat het ook zichtbaar was in de ListBox dat er meerdere items geselecteerd werden.
Ik zal het later op m'n werk eens verder uitzoeken.

https://fgheysels.github.io/

Pagina: 1