Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[C#]Onverwacht gedrag label/button text icm radiobuttons

Pagina: 1
Acties:

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

Topicstarter
Ik was een klein tooltje aan het maken toen ik tegen het volgende aan liep:

Er zitten drie radiobuttons in een GroupBox en er is een knop die wat zoekt op basis van de geselecteerde button.

Nu kan het even duren voor de actie is uitgevoerd, dus ik had het idee om de text van de button te veranderen in "Searching.." in het begin van de button_Click methode en dan weer terugzetten op het eind van de methode:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 private void button1_Click(object sender, EventArgs e)
        {
            button1.Text = "Searching..";
            if (radioButton1.Checked)
            {
                MessageBox.Show("button1");
            }
            else if (radioButton2.Checked)
            {
                MessageBox.Show("button2");
            }
            else 
            {
               MessageBox.Show("button3");
            }
            button1.Text = "Search";
        }

(het moge duidelijk zijn dat de normale code even is vervangen voor MessageBoxes voor de eenvoud ;) )

Wat na wat debuggen blijkt, is dat deze actie pas gebeurt ná het uitvoeren van de code in het if/else blok. Dus op het moment dat de MessageBox wordt getoond, verandert pas de text van de button.
ijdens het uitvoeren van de code gebeurt er dus niets met de button, totdat de MessageBox getoond wordt, terwijl het nou juist de bedoeling is dat die button text verandert om aan te geven dat er op de achtergrond wat gebeurt.

Toen ik daarna probeerde om een label met "Searching.." visible te maken en daarna weer te hiden, bleek deze van hetzelfde fenomoon last te hebben..

Het kan aan mij liggen, maar dit is toch niet logisch?

Kater? Eerst water, de rest komt later


  • Cloud
  • Registratie: November 2001
  • Laatst online: 03-11 10:25

Cloud

FP ProMod

Ex-moderatie mobster

Waarschijnlijk heb je
C#:
1
Application.DoEvents();

nodig. :) Deze moet je even uitvoeren vóór je MessageBox (direct na de aanpassing van de Text property). De MessageBox die meteen na de aanpassing komt, zorgt ervoor dat je applicatie nog niet repaint.

Zie ook application.doevents op MSDN.

edit:
Invalidate(); gevolgt door Update(); kan overigens ook helpen en schijnt wat 'netter' te zijn lees ik nu.

[ Voor 25% gewijzigd door Cloud op 09-07-2008 20:19 ]

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


  • PolarBear
  • Registratie: Februari 2001
  • Niet online
Ik heb even geen ontwikkelomgeving bij de hand maar is Control.Invalidate() of Control.Refresh() geen optie (vooral de laatste).

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

Topicstarter
Zowel "Invalidate(); gevolgt door Update();" als "Refresh()" werken :)

Kater? Eerst water, de rest komt later


Verwijderd

Wat Cloud zegt. Waarschijnlijk zijn de routines die je nu vervangen hebt door MessageBox zo druk bezig dat je main thread geen tijd heeft om de pending messages af te handelen. En 't setten van een Text op een control gebeurt via een Windows message.

Bij dingen die niet zoveel tijd kosten is DoEvents een goede oplossing, maar vooral in multithreaded situaties kan een geforceerde DoEvents voor problemen zorgen, je forceert dan de message pump alles af te handelen wat in de queue staat, en dat kan soms te vroeg zijn.
Bij taken die even duren maar waarbij je wil dat de UI responsief blijft zou ik die taak in een eigen thread uitvoeren (.NET maakt 't je wat dat betreft erg gemakkelijk met de BackgroundWorker en delegates).

Verwijderd

Inderdaad, als je zoekfunctie erg traag is kan je die ook in een aparte Thread gooien :). Hoef je verder ook niet te klooien met DoEvents of Refresh, en blijft heel je applicatie ook niet hangen ;).

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

Topicstarter
Ik heb het zoeken nu met een BackgroundWorker gedaan ja, nog nooit wat mee gedaan, maar is inderdaad niet zo heel lastig om te gebruiken.

Even een heel ander vraagje, het is zeker niet mogelijk om met een ProgressBar weer te geven hoever je bent met het recursief doorlopen van een mappenstructuur? (aangezien je vantevoren niet weet hoeveel mappen er zijn)

Kater? Eerst water, de rest komt later


  • Cloud
  • Registratie: November 2001
  • Laatst online: 03-11 10:25

Cloud

FP ProMod

Ex-moderatie mobster

Dat is lastig als je dat aantal mappen niet weet. Maar je kunt van tevoren het aantal mappen tellen toch? Gewoon één keer door de structuur heen lopen om te tellen en dan je proces daadwerkelijk starten. :) Misschien zijn er zelfs nog snellere/slimmere methoden om die telling te doen.

Kán een optie zijn. Is natuurlijk geheel afhankelijk van hoe lang je proces duurt; het tellen van de mappen moet natuurlijk wel vrij snel gedaan worden t.o.v. je proces.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Overigens had ik het persoonlijk wat fijner gevonden als de windows explorer wat minder 'diep' ging kijken hoeveel er precies gekopieerd moet worden. Door dat voorrekenen duurt het kopieren/verplaatsen vaak een stuk langer (er lijkt eerst een tijd niets te gebeuren). Helaas is de voortgangs balk in de explorer ook niet uit te schakelen. Ik neem genoegen met slechts een melding dat het kopieren/verplaatsen/verwijderen nog bezig is.

If it isn't broken, fix it until it is..


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

Topicstarter
Nog even over die BackgroundWorker, volgens het voorbeeld op MSDN kan je een operatie gewoon cancelen met bijvoorbeeld een button, je roept dan de CancelAsync() methode aan, die zet CancellationPending op true.

In de DoWork eventhandler van de backgroundworker heb ik de check
C#:
1
(if e.CancellationPending)  e.Cancel 

Maar mijn backgroundWorker blijft altijd op IsBusy true staan, zodat ik niet meer verder kan na een cancel.

edit:
Ik heb het al gevonden, er moet in de methode die wordt uitgevoerd ook nog gecheckt worden of CancellationPending true of false is.

[ Voor 13% gewijzigd door Haan op 10-07-2008 14:12 . Reden: al opgelost ]

Kater? Eerst water, de rest komt later

Pagina: 1