Hi guys,

I need some help on this one... I want this app to refill a datagridview every half minute, but as soon as my Timer's EventHandler executes FillCustomerList() I get an Exception:

InvalidOperationException:
The object '' was opened from another thread than the one it was created in.

How do I get around this?


Code:
    public partial class Main : Form
    {
        private ArrayList Customers = new ArrayList();
        private ArrayList UnitList = new ArrayList();
        private ArrayList UnitTypes = new ArrayList();
        private ArrayList TaskList = new ArrayList();

        private DataGridViewCellStyle standard;
        private DataGridViewCellStyle green;
        private DataGridViewCellStyle yellow;
        private DataGridViewCellStyle red;

        Driver driver = Driver.Instance;

        System.Timers.Timer myTimer;

        public Main()
        {
            InitializeComponent();

            standard = new DataGridViewCellStyle();
            standard.BackColor = Color.LightSteelBlue;
            standard.SelectionBackColor = Color.LightSteelBlue;
            
            green = new DataGridViewCellStyle();
            green.BackColor = Color.LightGreen;
            green.SelectionBackColor = Color.LightGreen;

            yellow = new DataGridViewCellStyle();
            yellow.BackColor = Color.Yellow;
            yellow.SelectionBackColor = Color.Yellow;

            red = new DataGridViewCellStyle();
            red.BackColor = Color.Red;
            red.SelectionBackColor = Color.Red;

            gridUnits.AutoGenerateColumns = false;
            gridTasks.AutoGenerateColumns = false;
            gridCustomers.AutoGenerateColumns = false;

            gridUnits.DefaultCellStyle = standard;
            gridTasks.DefaultCellStyle = standard;
            gridCustomers.DefaultCellStyle = standard;
        }

        private void Main_Load(object sender, EventArgs e)
        {
            try
            {
                gridCustomers.Size = new Size(this.Size.Width - 20, this.Size.Height - 100);
                chkCustomer.Location = new Point(5, gridCustomers.Size.Height - chkCustomer.Size.Height + 30);
                FillCustomerList();
                SetRowSize();
                SetFontSize();

                myTimer = new System.Timers.Timer();
                myTimer.Interval = 30000;
                myTimer.Elapsed += new ElapsedEventHandler(OnTick);
                myTimer.Start();
            }
            catch
            {

            }
        }

        private void OnTick(object sender, System.Timers.ElapsedEventArgs e)
        {
            FillCustomerList();
            SetRowSize();
            SetFontSize();
        }

        private void FillCustomerList()
        {
            try
            {
                Customers.Clear();
                gridCustomers.DataSource = null;
                gridCustomers.Rows.Clear();

                Customers = driver.GetAllCustomers();

                gridCustomers.DataSource = Customers;

                for (int i = 0; i < gridCustomers.Rows.Count; i++)
                    //TODO: Correct color according to status.
                    gridCustomers.Rows[i].Cells[1].Style = green;
            }
            catch
            {

            }
        }

        private void SetFontSize()
        {
            //Set Fonts to fill the screen.
            int i = gridCustomers.Size.Height / gridCustomers.Rows.Count;

            Font font = new Font("Calibri", i/3);
            gridCustomers.Font = font;
        }

        private void SetRowSize()
        {
            //Set rows to fill the screen.
            int rowcount = gridCustomers.Rows.Count;
            int height = gridCustomers.Size.Height;
            int average = height / rowcount;
            for (int i = 0; i < rowcount; i++)
            {
                gridCustomers.Rows[i].Height = average;
            }
        }