Search code examples
c#stringwinformstextboxmessagebox

TextBox.text only working followed by a Messagebox


All I want to do is to evaluate the X and Y values of the current mouse position with this simple code

 while (true)
            {
                textBox1.Text = Cursor.Position.X.ToString();
                //MessageBox.Show(""+Cursor.Position);
                Thread.Sleep(150);
            }

but it only seems to work when the MessageBox is uncommented otherwise it just writes nothing.

And if I initialize Cursor with a Panel.Handle it doesn't show the .position member;


Solution

  • Your problem is quite interesting. As you're using an endless loop, your form is never being updated (and either is your textbox). But if you add the messageBox, it seems as though the form is updated, if the messageBox is shown. So all you have to do is to put the endless loop into asynchronous context:

    Task.Run(async () => await Task.Run(() =>
        {
            while (true)
            {
                textBox1.Invoke(new Action(() => textBox1.Text = Cursor.Position.X.ToString()));
                Thread.Sleep(150);
            }
        }));
    

    You could achieve the same by using a timer:

    public Form1()
    {
        InitializeComponent();
        var timer1 = new Timer
        {
            Enabled = true,
            Interval = 150
        };
        timer1.Tick += timer1_Tick;
        timer1.Start();
    }
    private void timer1_Tick(object sender, EventArgs e)
    {
        textBox1.Text = Cursor.Position.X.ToString();
    }
    

    You should generally not use an endless loop on the main thread in forms applications, because otherwise your UI is freezing. Actually you could notice that I used textBox1.Invoke - this is there because you can't access UI elements on another thread than that they were created on.

    A more elegant way to solve this however would be to handle the MouseMove event:

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        textBox1.Text = $"Mouse location: {e.Location.X}, {e.Location.Y}";
    }
    

    I also changed the way the position is displayed (I used an interpolated string), as I think this is kind of more beautiful.

    For more information on asynchronous programming take a look at this: https://msdn.microsoft.com/de-de/library/mt674882.aspx