Avatar billede CodingJoe Nybegynder
12. marts 2011 - 21:56 Der er 13 kommentarer og
1 løsning

Progressbar

Jeg har forsøgt at finde noget brugbart på nettet...men har ikke haft heldet med mig.

Jeg har brug for at lave en progressbar in min winform app.

Den skal meget simpelt, sådan set omkranse en længere varende operation;

StartProgressBar();
...
StartLængerevarendeOperation();
...
FuldendProgressBar();

...og den skal naturlivis nulstilles igen, under min nulstil knap...

Er der ikke en, der kan sende mig hen i en rigtig retning...
Avatar billede arne_v Ekspert
12. marts 2011 - 22:58 #1
Et gammelt eksempel fra lageret:

using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Threading;

public class MainForm : Form
{
    private ProgressBar bar;
    private Button start;
    private Button abort;
    private Thread t;
    public MainForm()
    {
        bar = new ProgressBar();
        start = new Button();
        abort = new Button();
        SuspendLayout();
        bar.Location = new Point(50, 50);
        bar.Size = new Size(200, 50);
        bar.Name = "Progress Bar";
        start.Location = new Point(50,150);
        start.Size = new Size(200, 50);
        start.Name = "Start Button";
        start.Text = "Start";
        start.Click += new EventHandler(StartClick);
        abort.Location = new Point(50,250);
        abort.Size = new Size(200, 50);
        abort.Name = "Abort Button";
        abort.Text = "Abort";
        abort.Click += new EventHandler(AbortClick);
        ClientSize = new Size(300, 350);
        Controls.Add(bar);
        Controls.Add(start);
        Controls.Add(abort);
        Name = "Main Form";
        Text = "Main Form";
        ResumeLayout(false);
    }
    void Reset(int n)
    {
        bar.Minimum = 0;
        bar.Maximum = n;
        bar.Value = 0;
    }
    void Update(int n)
    {
        bar.Value = n;
    }
    delegate void ResetHandler(int n);
    delegate void UpdateHandler(int n);
    void Copy()
    {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.tmk.com/ftp/vms-freeware/fileserv/unzip.zip");
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        int tot = (int)resp.ContentLength;
        if(bar.InvokeRequired)
        {
            bar.Invoke(new ResetHandler(Reset), new object[] { tot });
        }
        else
        {
            Reset(tot);
        }
        Stream f1 = resp.GetResponseStream();
        Stream f2 = new FileStream(@"C:\unzip.zip", FileMode.CreateNew, FileAccess.Write);
        int sofar = 0;
        byte[] b = new byte[1000];
        int n;
        while((n = f1.Read(b, 0, b.Length)) > 0 )
        {
            f2.Write(b, 0, n);
            sofar += n;
            if(bar.InvokeRequired)
            {
                bar.Invoke(new UpdateHandler(Update), new object[] { sofar });
            }
            else
            {
                Update(sofar);
            }
        }
        f2.Close();
        f1.Close();
        resp.Close();
    }
    void StartClick(object sender, EventArgs e)
    {
        t = new Thread(new ThreadStart(Copy));
        t.Start();
    }
    void AbortClick(object sender, EventArgs e)
    {
        t.Abort();         
    }
    [STAThread]
    public static void Main(string[] args)
    {
        Application.Run(new MainForm());
        Application.Exit();
        Environment.Exit(0);
    }
}
Avatar billede arne_v Ekspert
12. marts 2011 - 22:59 #2
Der der delegates kan laves lidt smartere idag.
Avatar billede CodingJoe Nybegynder
12. marts 2011 - 23:39 #3
Yes! Det er jeg sikker på :)
...men hvor er det min 'StartProgressBar', 'MinLangeOperation' og min 'FuldendProgressBar' skal ind der? :)
Avatar billede CodingJoe Nybegynder
13. marts 2011 - 00:51 #4
I mit tilfælde har jeg ikke en løkke, men en sekventiel kørsel af nogle operation inde i en metode.
Vil sådan set bare starte prgressbar og slutte den som det sidste i min metode...
Avatar billede CodingJoe Nybegynder
13. marts 2011 - 00:59 #5
Avatar billede CodingJoe Nybegynder
13. marts 2011 - 01:10 #6
Det virkede ikke...progressbar startede efter min lange operation :(

...denne feature er Nice-to-have...men for at jeg få det til at se fedt ud...er det en Need-to-have for mig :S
Avatar billede arne_v Ekspert
13. marts 2011 - 01:23 #7
ProgressBar fungerer med :

bar.Minimum
bar.Maximum
bar.Value

hvor den sidste markerer hvor langt man er kommet.

Det behøver ikke være bytes - det kan også være metodekald.
Avatar billede CodingJoe Nybegynder
13. marts 2011 - 11:55 #8
Sorry, hvis det virker ret dumt...men... jeg kan ikke se hvad der animerer min progressbar.

Skal min implementering se således ud:

private void MinLangeOperation(){
  bar.Minimum

  (Kald af diverse operationer)
  bar.Value

  bar.Maximum
}

'Kald af diverse operationer' er i virkeligheden et kald mod en webservice, der kan være en smule længe om at svare....
Avatar billede arne_v Ekspert
13. marts 2011 - 15:14 #9
Lad os sige at du skal lave 3 web service kald.

bar.Minimum = 0;
bar.Maximum = 3;
bar.Value = 0;
// første kald
bar.Value = 1;
// andet kald
bar.Value = 2;
// tredie kald
bar.Value = 3;

Det ser ikke så advanceret ud med kun 3 kald, men med flere bliver det en flydende progress.
Avatar billede CodingJoe Nybegynder
13. marts 2011 - 23:01 #10
Jeg forsøgte med en backgroundworker...men droppede det også. Jeg kom ud i nogle exceptions, mens backgroundworker stadigvæk arbejdede, og man klikkede på start backgroundworker/progressbar igen...
Avatar billede arne_v Ekspert
14. marts 2011 - 00:28 #11
Kan du ikke disable start mens der kører noget?
Avatar billede CodingJoe Nybegynder
14. marts 2011 - 18:22 #12
Tjo...jeg vil følge op på denne på et senere tidspunkt...smid gerne et svar ind alligevel.
Avatar billede arne_v Ekspert
15. marts 2011 - 02:47 #13
Noget lidt moderniseret kode:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

namespace E
{
    public class MainForm : Form
    {
        private ProgressBar bar;
        private Button start;
        private Button abort;
        private Thread t;
        private volatile bool done;
        public MainForm()
        {
            bar = new ProgressBar();
            start = new Button();
            abort = new Button();
            SuspendLayout();
            bar.Location = new Point(50, 50);
            bar.Size = new Size(200, 50);
            bar.Minimum = 0;
            bar.Maximum = 100;
            bar.Value = 0;
            bar.Style = ProgressBarStyle.Continuous;
            start.Location = new Point(50,150);
            start.Size = new Size(200, 50);
            start.Text = "Start";
            start.Click += StartClick;
            abort.Location = new Point(50,250);
            abort.Size = new Size(200, 50);
            abort.Text = "Abort";
            abort.Click += AbortClick;
            ClientSize = new Size(300, 350);
            Controls.Add(bar);
            Controls.Add(start);
            Controls.Add(abort);
            Text = "Main Form";
            ResumeLayout(false);
            start.Enabled = true;
            abort.Enabled = false;
        }
        private void Something()
        {
            if(InvokeRequired)
            {
                Invoke((MethodInvoker)delegate() { start.Enabled = false; abort.Enabled = true; } );
            }
            else
            {
                start.Enabled = false;
                abort.Enabled = true;
            }
            for(int i = 0; i <= 100 && !done; i++)
            {
                if(bar.InvokeRequired)
                {
                    bar.Invoke((MethodInvoker)delegate() { bar.Value = i; } );
                }
                else
                {
                    bar.Value = i;
                }
                Thread.Sleep(100);
            }
            if(InvokeRequired)
            {
                Invoke((MethodInvoker)delegate() { start.Enabled = true; abort.Enabled = false; } );
            }
            else
            {
                start.Enabled = true;
                abort.Enabled = false;
            }
        }
        private void StartClick(object sender, EventArgs e)
        {
            t = new Thread(Something);
            t.Start();
            done = false;
        }
        private void AbortClick(object sender, EventArgs e)
        {
            done = true;
        }
        [STAThread]
        public static void Main(string[] args)
        {
            Application.Run(new MainForm());
            Environment.Exit(0);
        }
    }
}
Avatar billede arne_v Ekspert
15. marts 2011 - 02:47 #14
og et svar
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