ProgressBar WPF, aktualizacja wartości

0

Witam,
W swoim oknie posiadam kontrolkę progressbar. W innej klasie po zakończeniu metody jest zmieniane pole z innej klasy, które odpowiada za wartość paska. W klasie(oknie), w której znajduje się progressbar mam stworzony licznik i metody:

   private static System.Timers.Timer aTimer;
public Okno()
        {
            aTimer = new System.Timers.Timer(1100);
            myDel += Change;
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

            aTimer.Interval = 1000;
            aTimer.Enabled = true;
            aTimer.Start();
        }
   public void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            Pasep_Postepu.Dispatcher.Invoke(myDel);
        }
        delegate void Del();
        Del myDel;
        private void Change()
        {
            Pasep_Postepu.Value = OknoGlowne.LICZNIK_PASKA;
        }

Podczas wykonywania metody z innej klasy tak jak wspomniałem pole LICZNIK_PASKA jest zmieniane i dzięki timerowi powinno aktualizować postęp na pasku. Niestety taka konstrukcja mi nie działa. Pasek stoi w miejscu. Aby sprawdzić czy wartość paska jest zwiększana dodałem MessageBox wyświetlający wartość po zwiększeniu i w tym momencie gdy pojawia się okienko z wartością LICZNIK_PASKA, a progressbar poprawnie się aktualizuje. W czym jest problem?

0

Wygląda na to że program nie ma chwili żeby odetchnąć i obsłużyć kolejkę komunikatów
MessageBox modalnie blokuje wątek dopóki nie naciśniesz OK więc komunikaty są obsługiwane
Identycznie będzie gdy w tym miejscu napiszesz:

Application.DoEvents();

ale to nie jest rozwiązanie problemu

Potrzeba więcej kodu - prawdopodobnie wszystko się dzieje w jednym wątku
Jeżeli OknoGlowne.LICZNIK_PASKA jest typu prostego i ma być aktualizowane z innego wątku niż odczytywane to musi być zadeklarowane jako volatile - w przeciwnym wypadku w trybie Debug wszystko może grać, a w trybie Release nagle już nie

0

Więc, w OknieGlownym zdarzenie obsługi buttona

 {
            OknoDialogowe2 okno = new OknoDialogowe2();
            okno.Show();
            try
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
                zatwierdz_zmiany();
                Mouse.OverrideCursor = null;
            }
            catch { }
            okno.Close();
            
        }

oraz deklaracja:

 public static int LICZNIK_PASKA { get; set; }

Metoda zatwierdz_zmiany:

 public void zatwierdz_zmiany()
        {
            try
            {
                LICZNIK_PASKA = 0;

                Efekt.Stworz_bmp();
                
            }
            catch { MessageBox.Show("Kod Błędu:0x00027", Title = "Error 0x00027"); }
        }

W klasie Efekt w metodzie Stworz_bmp jest tworzone 120 bitmap(oraz ich zapis na dysku), po każdym narysowaniu i zapisaniu bmp:

  OknoGlowne.LICZNIK_PASKA++;

OknoDialogowe2 składa się z kontrolki label i progressbar:

public partial class OknoDialogowe2 : Window
    {
        private static System.Timers.Timer aTimer;
        public OknoDialogowe2()
        {
            InitializeComponent();
            this.Left = 600;
            this.Top = 500;
            aTimer = new System.Timers.Timer(500);
            myDel += Change;
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

            aTimer.Interval = 400;
            aTimer.Enabled = true;
            aTimer.Start();
        }
        public void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            Pasep_Postepu.Dispatcher.Invoke(myDel);
        }
        delegate void Del();
        Del myDel;
        private void Change()
        {
            Pasep_Postepu.Value = OknoGlowne.LICZNIK_PASKA ;
        }

    }

aż się boje komentarzy na temat kodu :D

0

Bardzo niekonsekwentne nazywanie zmiennych. Co do problemu to zapoznaj się z pojęciem "Background Worker".

1 użytkowników online, w tym zalogowanych: 0, gości: 1