-1

This is my code but label1 runs first before label2 does? What I wanted is to run label1 and label2 at the same time on their respective threads. I've use threads by the way but it cannot access controls except in its own thread where it is created. So in this code, when I create instance such as: Slave s1 = new Slave(label1); Slave s2 = new Slave(label2); it will automatically start moving the two labels, but its not.

public class Slave
{
    private Label l;
    private BackgroundWorker bw;
    public Slave(Label l)
    {
        this.l = l;
        bw = new BackgroundWorker();
        bw.WorkerReportsProgress = true;
        bw.DoWork+=new DoWorkEventHandler(worknow);
        bw.ProgressChanged += new ProgressChangedEventHandler(update);
        bw.RunWorkerAsync();
    }
    private void worknow(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker b = sender as BackgroundWorker;
        b.ReportProgress(1);
    }
    private void update(object sender, ProgressChangedEventArgs e)
    {
        for(int x=0; x<20;x++)
        {
            l.Top += 10;
            System.Threading.Thread.Sleep(100);
        }
    }

}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
Al-Mujahedeen
  • 11
  • 1
  • 5
  • When you searched for the exact text of the exception message you received, what did you find? Did you try to incorporate any of the suggestions you found? What happened when you did? – Peter Duniho Dec 07 '14 at 01:59
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Dec 07 '14 at 02:01
  • Another thread can modify GUI elements: http://stackoverflow.com/questions/527947/invoke-required – Steve Wellens Dec 07 '14 at 02:02
  • Are you referring to the threads I used before? Well I found a solution from google but its difficult to understand and some said its better to use backgroundworker for this kind of problem. One must be very careful when using threads because its risky and prone to complex errors, as they said. – Al-Mujahedeen Dec 07 '14 at 02:07
  • An easy solution can be just put both labels in a panel and instead of moving the label, move the panel – Dom Stepek Dec 07 '14 at 03:32

1 Answers1

0

Okay I just found out the solution to my problem so I'll answer my own question, so I have a winform with 1 panel and a button so simple, so I have a class Animate such that Animate a = new Animate(panel1,startingX,startingY,newX,newY); instantiation will create a Node at starting location and move it to the desired new location every 100 milliseconds in a click of a button the definition of the class node is shown below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
   class Node:Label
   {
      public Node(int x, int y)
        {
            this.Top = y;
            this.Left = x;
        }
        public void updatePos(int x, int y)
        {
            this.Top += y;
            this.Left += x;
        }
   }
}

Then this is the definition of the animate class:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Animate a = new Animate(panel1,0,0,1,1); //this is the actual instatiation test
        Animate b = new Animate(panel1, 100, 0,2,2); //for node b

    }

    public class Animate
    {
        private Node l;
        Thread th;
        private delegate void cl(int x, int y);
        Delegate del;
        private int a, b;

        public Animate(Panel p, int x, int y, int a, int b)
        {
            l = new Node(0,0);
            del = new cl(l.updatePos);
            this.a = a;
            this.b = b;

            this.l.AutoSize = true;
            this.l.Location = new System.Drawing.Point(x, y);
            this.l.Name = "label1";
            this.l.Size = new System.Drawing.Size(35, 13);
            this.l.TabIndex = 0;
            this.l.Text = "label1";
            p.Controls.Add(l);

            th = new Thread(thread);
            th.Start();
        }
        private void thread()
        {
            while (true)
            {
                try
                {
                    l.Invoke(del, a, b);
                    Thread.Sleep(100);
                }
                catch (Exception e)
                {
                    return;
                }
            }
        }
    }
}

}

Some might wonder what am I needing this for, well I am trying to implement a Binary Search Tree and AVL simulator using purely C# coded winform application only, that's why Im calling a label a "Node"

Al-Mujahedeen
  • 11
  • 1
  • 5