Avatar billede henrik_40 Juniormester
03. februar 2013 - 03:52 Der er 11 kommentarer og
1 løsning

Grafik på Windows Form

Hej
Jeg har prøvet alt muligt uden held. Jeg vil gerne tegne grafik på windows-formen samtidigt med at jeg får en mand til at løbe ved at gøre Picturebox visible = false /sand.

1) mand som løber:

        private void FillFlintstone(int sleepfactor)
        {
            pictureBoxFlint1.Visible = true;
            Thread.Sleep(sleepfactor);
            pictureBoxFlint1.Visible = false;
            pictureBoxFlint2.Visible = true;
            Thread.Sleep(sleepfactor);
            pictureBoxFlint2.Visible = false;
            pictureBoxFlint3.Visible = true;
            Thread.Sleep(sleepfactor);
            pictureBoxFlint3.Visible = false;
            pictureBoxFlint4.Visible = true;
            Thread.Sleep(sleepfactor);
            pictureBoxFlint4.Visible = false;
            pictureBoxFlint5.Visible = true;
            Thread.Sleep(sleepfactor);
            pictureBoxFlint5.Visible = false;
            pictureBoxFlint6.Visible = true;
            Thread.Sleep(sleepfactor);
            pictureBoxFlint6.Visible = false;
            pictureBoxFlint7.Visible = true;
            Thread.Sleep(sleepfactor);
            pictureBoxFlint7.Visible = false;
            pictureBoxFlint8.Visible = true;
            Thread.Sleep(sleepfactor);
            pictureBoxFlintEnd.Visible = true;
        }


2) Barometer som tegner streger stablet ovenpå hindanden

        public void FillBarometer(int count, string colorcode, int sleepfactor, ref int coordinates)
        {

            System.Drawing.Pen myPen;
            pictureBoxHumorBarometer.Visible = true;

            myPen = new System.Drawing.Pen(ColorTranslator.FromHtml(colorcode));
            System.Drawing.Graphics formGraphics = this.CreateGraphics();
            int temp = 0;
            for (int i = 0; i < count; i++)
            {
                temp = coordinates - i;
                Thread.Sleep(sleepfactor);
                Point point1 = new Point(30, coordinates - i);
                Point point2 = new Point(75, coordinates - i);
                formGraphics.DrawLine(myPen, point1, point2);
            }
            coordinates = temp;
            myPen.Dispose();
            formGraphics.Dispose();
        }



Kan nogle hjælpe mig?
Avatar billede arne_v Ekspert
03. februar 2013 - 03:58 #1
Jeg gaetter paa at dit problem er at der ikke sker noget foerend slut status vises.

Og at det skyldes at din Thread.Sleep blokerer for skaerm opdateringer.

Og at loesningen er at starte en separat traad og opdatere GUI via Invoke.
Avatar billede arne_v Ekspert
03. februar 2013 - 03:59 #2
Eksempel:

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

public class MainForm : Form
{
    private Label time;
    private Button start;
    private Button abort;
    private Thread t;
   
    public MainForm()
    {
        time = new Label();
        start = new Button();
        abort = new Button();
        SuspendLayout();
        time.Location = new Point(50, 50);
        time.Size = new Size(300, 50);
        time.Font = new Font(FontFamily.GenericSerif, 16.0f);
        start.Location = new Point(50,150);
        start.Size = new Size(200, 50);
        start.Name = "Start Button";
        start.Text = "Start clock";
        start.Click += StartClick;
        abort.Location = new Point(50,250);
        abort.Size = new Size(200, 50);
        abort.Name = "Abort Button";
        abort.Text = "Abort clock";
        abort.Click += AbortClick;
        ClientSize = new Size(400, 350);
        Controls.Add(time);
        Controls.Add(start);
        Controls.Add(abort);
        Name = "Main Form";
        Text = "Main Form";
        ResumeLayout(false);
    }
    public void Run()
    {
        while(true)
        {
            if(time.InvokeRequired)
            {
                time.Invoke((Action)(() => time.Text = DateTime.Now.ToString()));
            }
            else
            {
                Update();
            }
            Thread.Sleep(1000);
        }
    }
    public void StartClick(object sender, EventArgs e)
    {
        t = new Thread(Run);
        t.Start();
    }
    public 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 henrik_40 Juniormester
03. februar 2013 - 12:52 #3
Hej
Tak for svaret. Det lyder meget rigtigt det du siger og jeg har afprøvet dit eksempel med uret som virker.

Jeg kan desværre ikke få mit eget til at virke. Håber du kan hjælpe mig videre.

Formen skal kaldes fra en hovedform.

Som du kan se af mit oprindelige spørgsmål bliver, bliver baren tegnet fra koden, imens jeg har lavet picturebox'es i Design-view.

1) skal pictureboxene også defineres i koden (som du gør med dine labels og buttons)?
(det må være det som hedder           
SuspendLayout();
  def. af pictureboxe
ResumeLayout(false);

Jeg har forsøgt mig at overføre din kode til mit eget problem, men det går desværre galt og crasher:

    public partial class FormTest : Form
    {
        private Thread t;

        public FormTest()
        {
            InitializeComponent();

            t = new Thread(FillFlintstone);
            t.Start();
            t.Abort();
        }

        private void FillFlintstone()
        {
            pictureBoxFlint1.Invoke((Action)(() => pictureBoxFlint1.Visible = true));
            Thread.Sleep(10);

            pictureBoxFlint1.Invoke((Action)(() => pictureBoxFlint1.Visible = false));
            Thread.Sleep(10);
           
            pictureBoxFlint2.Invoke((Action)(() => pictureBoxFlint2.Visible = true));
            Thread.Sleep(10);
        }
    }


3) vil du give mig et lille eksempel på at pictureboxene bliver visible og ikke-visible, så kan jeg måske komme videre derfra selv?
Avatar billede henrik_40 Juniormester
03. februar 2013 - 14:24 #4
Eller måske nemmere at have en picturebox som bare skifter koordinater og billede med thread.sleep for hvert billede.
Avatar billede arne_v Ekspert
03. februar 2013 - 16:52 #5
Jeg har et andet eksempel med PictureBox:

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

public class MainForm : Form
{
    private const int D = 20;
    private const int W = 400;
    private const int H = 400;
    private static readonly Random rng = new Random();
    private int x;
    private int y;
    private int dx;
    private int dy;
    private PictureBox pic;
    private Timer t;
    public MainForm()
    {
        x = rng.Next(0, W-D);
        y = rng.Next(0, H-D);
        dx = rng.Next(1, 5);
        dy = rng.Next(1, 5);
        pic = new PictureBox();
        pic.Location = new Point(0, 0);
        pic.Size = new Size(W, H);
        pic.Paint += BallPaint;
        Controls.Add(pic);
        Resize += Mirror;
        ClientSize = new Size(W, H);
        t = new Timer();
        t.Interval = 10;
        t.Tick += BallMove;
        t.Start();
    }
    private void Mirror(object sender, EventArgs evt)
    {
        pic.Size = this.ClientSize;
    }
    private void BallMove(object sender, EventArgs evt)
    {
        x += dx;
        y += dy;
        if(x < 0)
        {
            x = 0;
            dx = -dx;
            dy += rng.Next(-1, 1);
        }
        if(x > pic.Width - D)
        {
            x = pic.Width - D;
            dx = -dx;
            dy += rng.Next(-1, 1);
        }
        if(y < 0)
        {
            y = 0;
            dx += rng.Next(-1, 1);
            dy = - dy;
        }
        if(y > pic.Height - D)
        {
            y =  pic.Height - D;
            dx += rng.Next(-1, 1);
            dy = - dy;
        }
        pic.Invalidate();
    }
    private void BallPaint(object sender, PaintEventArgs evt)
    {
        evt.Graphics.FillEllipse(new SolidBrush(Color.Blue), x, y, D, D);
    }
    [STAThread]
    public static void Main(string[] args)
    {
        Application.Run(new MainForm());
    }
}

det bruger saa en Timer fremfor en Thread, men  ...
Avatar billede arne_v Ekspert
03. februar 2013 - 16:53 #6
"men det går desværre galt og crasher"

kan jeg ikke udlede noget som helst af
Avatar billede henrik_40 Juniormester
03. februar 2013 - 17:28 #7
Hej Arne
nej sorry du kan ikke udlede noget af "galt og crasher".  Jeg er bare i panik, skulle have lavet min appl i går :-(, så jeg var frustreret..

Jeg har videreført dit første thread-forslag og fået en grafik til at løbe hen over skærmen.

Jeg går videre med at indsætte barometer, som skal køre samtidigt med grafikken (manden) der løber hen over skærmen. Jeg vedhæfter min kode for at høre om jeg er på rette vej. Og høre om jeg "bare" skal lave en Thread2-variable og starte den i formload, sammen med den anden?

    public partial class FormTest : Form
    {
        private PictureBox pb;
        private Thread t;

        int pictureX = 717; int pictureY = 391;
        public FormTest()
        {
            InitializeComponent();

            pb = new PictureBox();
            SuspendLayout();
            pb.Location = new Point(pictureX, pictureY);
            pb.Size = new Size (163, 148);
            pb.Image = new Bitmap(@"C:\Henrik\Caroline\Caroline\Images\Flintstone\flint1.png");

            ClientSize = new Size(900, 590);
            Controls.Add(pb);
            Name = "Main Form";
            Text = "Main Form";
            ResumeLayout(false);
        }

        private void FormTest_Load(object sender, EventArgs e)
        {
            t = new Thread(FlintStone);
            t.Start();
        }

        public void FlintStone()
        {
            for (int i = 50; i < 400; i = i+10)
            {
                if (pb.InvokeRequired)
                {
                    pb.Invoke((Action)(() =>  pb.Location = new Point(pictureX-i, pictureY)));
                }
                else
                {
                    Update();
                }
                Thread.Sleep(300);
            }
        }
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            pb.Dispose();
        }
    }
Avatar billede arne_v Ekspert
03. februar 2013 - 18:25 #8
Hvis de to ting skal koere uafhaengigt af hinanden, saa var to traade oplagt.
Avatar billede henrik_40 Juniormester
03. februar 2013 - 18:43 #9
ja det er det som der skal, og ovenstående kode er vel som du har fortalt mig?

Så det er den første tråd.

Men FillBarometer har jeg stadig ikke kunne finde ud af som tråd, der er jo ikke noget objekt jeg kan "invoke"?

.. og så skal den kaldes flere gange med forskellige Colorcodes (kunne måske klares i et array, så den kun kaldtes en gang)

Ved ikke om du kan hjælpe mig med dette også (selvom du allerede har hjulpet mig meget).

        public void FillBarometer(int count, string colorcode, int sleepfactor, ref int coordinates)
        {

            System.Drawing.Pen myPen;
            pictureBoxHumorBarometer.Visible = true;

            myPen = new System.Drawing.Pen(ColorTranslator.FromHtml(colorcode));
            System.Drawing.Graphics formGraphics = this.CreateGraphics();
            int temp = 0;
            for (int i = 0; i < count; i++)
            {
                temp = coordinates - i;
                Thread.Sleep(sleepfactor);
                Point point1 = new Point(30, coordinates - i);
                Point point2 = new Point(75, coordinates - i);
                formGraphics.DrawLine(myPen, point1, point2);
            }
            coordinates = temp;
            myPen.Dispose();
            formGraphics.Dispose();
        }
Avatar billede arne_v Ekspert
04. februar 2013 - 00:37 #10
Du kan kalde Invoke paa hvad som helst f.eks. din Form.
Avatar billede henrik_40 Juniormester
04. februar 2013 - 20:48 #11
Tak for dine eksempler. Jeg fik løst min opgave, men dog på en lidt anden måde end jeg egentlig ville (en tråd pr. process som du skriver om).

Jeg må sætte mig mere ind i threads en dag.

Læg et svar til mig.
Avatar billede arne_v Ekspert
11. februar 2013 - 03:10 #12
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
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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