Avatar billede theill Nybegynder
15. april 2000 - 20:14 Der er 6 kommentarer og
1 løsning

Enable controls paa et ListView OnChange

Er der en standard maade, hvordan man disabler og enabler controls hvis fx en given selection er lavet i et listview?

Jeg har en knap der hedder 'delete'. Den skal KUN vaere enabled, hvis der er valgt et item i mit listview. Listview'et har _ikke_ multiselect, saa jeg skal 'bare' tjekke for, om et item 'ListView1->Selected' er != NULL. Nu er problemet bare, at hvis jeg laver mit tjek i 'OnChange' paa et listview, bliver mit tjek udfoert flere gange....hvilket jeg ikke er interesseret i. Hvis man har tre items, hvoraf det foerste er valgt og man nu vaelger item 2, faar man en 'OnChange' paa foerste item (fordi det mister sin 'selected' state) og derefter faar man et OnChange paa andet item (da det faar sin 'selected' state).

I MELLEM disse to events, har jeg intet valgt item, saa mit tjek disabler min 'delete' knap ... dog kun i faa millisekunder ... nemlig til item 2 faar en OnChange event.

Hvis man kun disabler een simpel control, kan man sikkert ikke se, at den skifter state hurtigt, men hvis man disabler fx 10-15 controls kan man se den blinke og det er ret irriterende.

Er der en 'standard' maade paa, hvordan man laver et 'enable/disable' control tjek? Det sker jo mange steder, at man vil disable en control, hvis der ikke er noget selected ... taenk bare paa de ofte brugte 'copy/cut/paste' kommandoer.
Avatar billede sjensen Nybegynder
16. april 2000 - 00:29 #1
Yes,

Oprettede OnxxxEvent nulstilles med følgende:

form1.onxxx := nil;

og den aktiveres med

form1.onevent := usereventname;

Avatar billede theill Nybegynder
16. april 2000 - 02:30 #2
sjensen >> den tror jeg ikke, jeg er helt med paa. Jeg er ikke interesseret i at disable et givent event, men derimod en control (fx TButton, TEdit, TMemo, etc). Dets 'enabled' state afhaenger saa af, om der er valgt noget i mit listview.
Avatar billede sjensen Nybegynder
16. april 2000 - 08:28 #3
lav en procedure a la

procedure Tform1.set_control(b : boolean);
begin
  Button1.enabled := b;
end;

denne procedure kan du så kalde med hhv. false eler true og dermed sætte button1 enabled eller disabled afhængig af parametren b.

Samtidig kan du bruge proceduren sammen med en test på om der er valgt noget i din listboks:

set_control(listbox1.itemindex <> -1);

Hvis listbox1.itemindex = -1 er listboksen enten tom eller også er der ikke valgt noget. Hvis itemindex = 0 eller større er der valgt en linie. Testen (listbox1.itemindex <> -1) vil derfor være true hvis der er valgt noget og false hvis der ikke er valgt eller listen er tom.

På den måde sætter proceduren din button1 enabled når der er valgt noget (enabled := true) og false når der ikke er valgt eller når den er tom.

Kaldet til procedures skal du så sætte i listboxens onchange eller onclick event, eller hvor du ellers synes du skal kalde den.

Du kan desuden udvide proceduren med et object, således at samme procedure kan sætte andre controls end din button1:

procedure Tform1.set_control(var cont : TObject;b : boolean);  // husk at cont skal være en VAR parameter
begin
  cont.enabled := b;
end;

og kaldet vil så være f.eks:

set_control(Button1,(listbox1.itemindex <> -1));

Meget mere generelt kan det vist ikke blive.
Avatar billede sjensen Nybegynder
16. april 2000 - 08:34 #4
Jeg glemte lige at sige med hensyn til det med at dine controls blinker når de skifter status:

Hvis jeg husker rigtigt findes der til hver object en generel procedure der hedder noget i retning af "Disablecontrols" og tilsvarende en "Enablecontrols".

Disse forhindrer at der sker opdatering af skærmen mellem de 2 kald. Du bør kunne sætte dem for din form eller den container der er far til dine kontroller (f.eks. panel1) lige før du skal ændre status og igen lige efter at alle kontrollers status er ændret.

Prøv engang at checke hjælpen !
Avatar billede theill Nybegynder
16. april 2000 - 11:15 #5
Bemaerk, at det ikke en en listbox, men derimod et *listview* jeg snakker om.

>>
Kaldet til procedures skal du så sætte i listboxens onchange eller onclick event, eller hvor du ellers synes du skal kalde den.
<<

Problemet er netop, at paa et listview, hvor jeg vaelger et nyt item (har et andet selected), vil jeg faa et tidspunkt, hvor 'ListView1.Selected' er NULL. Det er et problem, da jeg saa disabler mine knapper...men enabler dem 2 split efter .. nemlig naar jeg faar et nyt OnChange event paa det valgte listview.

Det virker som det skal, hvis jeg klikker paa mit listview, men ikke paa noget listitem. Der bliver smidt et OnChange event paa det item der mister sin selected state (jeg saetter controls til disabled).

Hvis der i stedet vaelges et nyt item, faar jeg en OnChange paa det gamle (mister focus) og jeg disabler mine knapper. Derefter kommer der et nyt OnChange paa det nyvalgte item ... som enabler mine knapper.

Jeg kan lave et sample program til dig, hvis det hjaelper paa min forklaring. Det er maaske lidt svaert at formulere.
Avatar billede sjensen Nybegynder
17. april 2000 - 09:30 #6
du kan jo ikke blæse og have mel i munden:

D.v.s. ikke både få onchange til at reagere når du vil og når du ikke vil, uden selv at gøre noget.

Men.. Hvis du så glemmer onchange på listview items, og i stedet bygger dine ønsker ind i application.onidle (der er en event du skal skal sætte op via formens create eller show, så kan du i den kigge på hvad der sker. Den bliver jo kaldt når programmet ikke laver andet og om den når at blive kaldt mellem de to selections, ved jeg faktisk ikke.

En anden mulighed er at sætte en timer aktiv (med f.eks. 100 msek eller hvad du vi) i listview.items onchange event (og kun sætte den hvis den ikke allerede er aktiv), og samtidig sætte en status (var du har oprettet) til false hvis der ikke er selectet noget og eller til true hvis der er selected noget, og ved timerens udløb kalder den procedure jeg anbefalede i et tidligere svar. Med timeren burde du kunne vente indtil brugeren har selected /deselected det han/hun vil, og når den trigger (d.v.s når tiden er udløbet) disabler timeren sig selv og sætter dine controls til den værdi VAR'en har på det tidspubkt. Var'en kan jo så i mellemtiden have nået at blive sat true/false et antal gange afhængig af hvad brugeren har trykket på, men det er lige meget fordi dine controls først bliver opdateret når tiden er gået.




Avatar billede theill Nybegynder
17. april 2000 - 11:06 #7
Jeg har selv taenkt paa en timer, men da det er en major hack, havde jeg haabet paa en mere ren loesning. Spoergsmaal var mere lavet for, at finde ud af, om der findes en 'standard' maade paa, hvordan problemet loeses ... og det kan vaere, at det goeres vha timere.

Men sjensen, jeg takker for din ihaerdighed og tildeler dig selvfoelgelig pointene.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester