-1

I have this code where i click control + m :

void gkh_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode == System.Windows.Forms.Keys.LControlKey) || (e.KeyCode == System.Windows.Forms.Keys.RControlKey))
            {
                controlDown = true;
            }

            if (e.KeyCode == System.Windows.Forms.Keys.M && controlDown)
            {
                backgroundWorker1.RunWorkerAsync();

Then the backgroundworker do work event:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            if (mf1 == null)
            {
                mf1 = new MagnifierForm(mConfiguration, System.Windows.Forms.Cursor.Position);
                mf1.Show();
            }
        }

I used a breakpoint and its getting to the MagnifierForm constructor and do everything there but when i click continue i never see this MagnifierForm form . Why ?

EDIT**

The reason i wanted to use backgroundworker to show the new form is that in the main form where i show the new form i have a timer tick event and for some reason this timer when its running only when its running making the new form to be show on a different location from the mouse cursor and the the form is moving/sliding to where the mouse cursor is. When the timer is not working there is no problems i show the new form and its showing it exactly where the mouse cursor is.

I dont know why this timer event make the problem and the timer is not connected by anything to the new form i want to show.

This is the timer event i have in the main form:

private void timer2_Tick(object sender, EventArgs e)
        {
            label1.Visible = true;
            if (counter == 200)
            {
                timer2.Enabled = false;//counter = 0;
                return;
            }
            counter += 1;
            distance = (float)counter;
            CloudEnteringAlert.cloudalert(bitmapwithclouds, distance);
            pictureBox1.Invalidate();

Now i found that if i remove for the test the line:

CloudEnteringAlert.cloudalert(bitmapwithclouds, distance);

And the timer is working there is no problem. The new form is show exactly where the mouse cursor is. This is the cloudalert method that making the problem and i dont know why:

public static List<PointF> cloudalert(Bitmap bmp, float kilometers)
        {
            AddDistanceToPoints = new List<PointF>();
            Color c1 = Color.White;
            Color c2 = Color.FromArgb(c1.A,
                (int)(c1.R * 1), (int)(c1.G * 1), (int)(c1.B * 1));
            Load();
            float distance = kilometers / (float)1.09;
            clouds = new List<PointF>();
            clouds1 = new List<PointF>();
            file = Path.GetDirectoryName(Application.LocalUserAppDataPath) + "\\Data" + "\\Data.txt";
            OptionsFile setting_file = new OptionsFile(file);
            LoadPoints_X = setting_file.GetListFloatKey("Points Coordinates X");
            LoadPoints_Y = setting_file.GetListFloatKey("Points Coordinates Y");
            for (int i = 0; i < PointsFloat.Count; i++)
            {
                //clouds1.Add(new PointF(LoadPoints_X[i] - distance, LoadPoints_Y[i]));
                AddDistanceToPoints.Add(new PointF(PointsFloat[i].X - distance, PointsFloat[i].Y));
            }
            bmp = FastComparison(bmp, Properties.Resources.clean_radar_image);
            newbitmap = bmp;
            for (int x = 0; x < AddDistanceToPoints.Count; x++)//clouds1.Count; x++)
            {
                if (AddDistanceToPoints[x].X > 0)//clouds1[x].X > 0)
                {
                    //Color color = bmp.GetPixel((int)clouds1[x].X, (int)clouds1[x].Y);
                    Color color = bmp.GetPixel((int)AddDistanceToPoints[x].X, (int)AddDistanceToPoints[x].Y);
                    int dR = (int)color.R;
                    int dG = (int)color.G;
                    int dB = (int)color.B;
                    if (dR == 0 && dG == 0 && dB == 0)
                    {

                    }
                    else
                    {
                        //clouds.Add(new PointF(clouds1[x].X, clouds1[x].Y));
                        clouds.Add(new PointF(AddDistanceToPoints[x].X, AddDistanceToPoints[x].Y));
                        //newbitmap.SetPixel((int)clouds1[x].X, (int)clouds1[x].Y, Color.White);
                        newbitmap.SetPixel((int)AddDistanceToPoints[x].X, (int)AddDistanceToPoints[x].Y, Color.White);

                    }
                }

            }
            //newbitmap.Save(@"d:\test\newbitmap.jpg");
            if (clouds.Count == 0)
            {
                cloudsfound = false;
                cloudsdistance.Text = distance.ToString();
                //clouds = null;
                return clouds
;
            }
            else
            {
                cloudsfound = true;

                for (int i = 0; i < clouds.Count; i++)
                {
                    pointtocolor.Add(clouds[i]);
                    cloudsdistance.Text = distance.ToString();
                }
            }
            return clouds;
        }

And in the main form im showing the new form by button click for example:

private void button1_Click(object sender, EventArgs e)
        {
            if (mf1 == null)
            {
                mf1 = new MagnifierForm(mConfiguration, System.Windows.Forms.Cursor.Position);
                mf1.Show();
            }
        }

Then why this timer tick event or more why this method cloudalert making the form mf1 to be show on a different location for a second and then the form slide/moving to where the mouse cursor is. But when this method i remove it or stop the timer and show the new form so there is no problems the form is show right where the mouse cursor is.

And the new form i show it at any place on the screen i dont show it only over the main form i show it where ever the mosue cursor is. The mouse can be on the taskbar or at 0,0 of the screen or anyplace and then i click button1 or i have global keys hook so i make Ctrl + M

And when the timer is running with this method cloudalert the form is show at some different location then move slide to the place of where the mouse cursor is.

You can get the new form im trying to show that is a magnifying glass here:

http://www.codeproject.com/Articles/18235/Simple-Magnifier

What im trying to do is not using this magnifier menu it have but using my button click event or the ctrl + m keys to show the magnifier glass form. But i have this problem.

If im using this magnifier menu and timer is working with the method there is no problems.

Strange cant figure out where is the problem with my timer2/method cloudalert.

user3200169
  • 275
  • 4
  • 17
  • Calling Show() from a bgw thread ought to throw an Exception... In Debug mode at least. – H H Jan 25 '14 at 21:25
  • The reason i wanted to use a backgroundworker and show the form there is that if i show the form in the ui form code i have a timer there that i need to run it and this timer make the new form to be show on a certain point/location on screen and then move/slide to where the mouse cursor is. I dont why is that. I dont know why the timer make it happen. But now when i used the backgroundworker even if the timer is working the new form is show where the mouse cursor is. But you told me not to use this ui in the backgroundowrker. So how else can i do something like that ? – user3200169 Jan 25 '14 at 21:32
  • Something like that so when the timer is working the new form will be show like its not connected to the form im showing it from so the timer wont interrupt it. – user3200169 Jan 25 '14 at 21:33
  • What Timer class? .NET has at least 3. – H H Jan 25 '14 at 21:35
  • The timer is from the designer from the toolbox the regular timer you drag from the toolbox and then i make timer tick event. – user3200169 Jan 25 '14 at 22:00
  • System.Windows.Forms.Timer – user3200169 Jan 25 '14 at 22:01
  • Edited my question tried to explain the problem its a bit long but its all connected. – user3200169 Jan 25 '14 at 23:25

2 Answers2

3

First - do not work with UI from multiple threads. If you want to display something when worker completes execution, then handle RunWorkerCompleted event (this handler runs on main thread):

void backgroundWorker1_RunWorkerCompleted(
    object sender, RunWorkerCompletedEventArgs e)
{
    if (mf1 == null)
    {
        mf1 = new MagnifierForm(mConfiguration, Cursor.Position);
        mf1.Show();
    }
}

Second - your code is not working, because background thread exits. If you would change mf1.Show() to mf1.ShowDialog() then you'll see your form.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • Sergey this mf1.ShowDialog() solved my problem with the timer. I described above the problem with the timer i have in the form where i show the new form. But since using ui in the backgroundworker is bad thing what else can i do ? – user3200169 Jan 25 '14 at 21:35
  • @user3200169 Timer.Tick event handler will be executed on main thread - there should not be any problems with showing form. Maybe you a firing event many times in a row? – Sergey Berezovskiy Jan 25 '14 at 22:27
1

DoWork is run in a worker thread. You shouldn't try to change your UI from there, but only from your main UI thread.

zmbq
  • 38,013
  • 14
  • 101
  • 171