C # Почему мой Picturebox не движется, когда функция рисования вызывается таймером? - PullRequest
0 голосов
/ 16 ноября 2018

Я создаю простое приложение, которое очищает XML-файл, относящийся к состоянию некоторых станков, которые выводят данные с датчиков в реальном времени, и использует координаты X / Y устройства, чтобы заставить крысу немного танцевать по экрану. Крыса помещается в правильное положение при первом опросе машины, но не перемещается каждый раз, когда функция извлечения вызывается последующими событиями, управляемыми таймером.

Я предположил, что это было только из-за того, что машина находилась в режиме ожидания, и единственными изменениями координат были небольшие колебания сервопривода, но просто для проверки я создал генератор случайных чисел и заставил систему использовать случайно сгенерированные координаты вместо масштабированного X / Y данные поступают.

Затем я обнаружил, что крыса не двигается! Это функция, в которой я рисую крысу (ов) (есть 2 системы, но мы сейчас беспокоимся только о «bakugo»). Мы особенно обращаем внимание на if (dekuWake == false) и (bauwake == true); Здесь у меня были значения, напечатанные на консоли (управляемые таймером), и «system.drawing.point (s)» показаны как действительные (в диапазоне и при изменении).

Таймер запускается кнопкой в ​​форме 1. Событие Timer вызывает функцию опроса, которая удаляет переменные XY с сайта (см. Мой вопрос здесь об этой функции - Что не так с моим использованием XPath в C #? ) На этом этапе он выясняет, был ли статус «ДОСТУПЕН» (который он есть), и устанавливает для «крысиного» «пробужденного» bool значение «истина» (определяет, какие изображения отрисовываются, если машина находится в автономном режиме, «крыса» остается в своем поле) Затем масштабирует координаты до разрешения окна программы. (Обычно, сейчас он шагает по 2 массивам целых чисел, сгенерированных при первом запуске опроса. Функция обновления координат устанавливает координаты X, Y для ImageRat.Bakugo) и вызывает drawRats ().

Почему изменение местоположения моих изображений фактически не перемещает коробки с картинками?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Drawing;
using System.Windows.Forms;
namespace XMLRats3
{
    public class Drawing 
    {
        private PictureBox HouseImage;
        private PictureBox DekuImage;
        private PictureBox BakuImage;

        public Drawing(PictureBox house, PictureBox deku, PictureBox baku)
        {
            HouseImage  = house;
            DekuImage   = deku;
            BakuImage   = baku;
        }
        public void ClearRats()
        {
            HouseImage.Hide();
            DekuImage.Hide();
            BakuImage.Hide();
        }

        public void DrawRats(bool DekuWake, bool BakuWake) // Call this function using active status of 2 machines
        {
            ClearRats();

            /*// This shows that the generated coordinates are reaching this point successfully
            Console.WriteLine("BAKU X: " + ImageRat.Bakugo.PosX);
            Console.WriteLine("BAKU Y: " + ImageRat.Bakugo.PosY);
            */

            System.Drawing.Point DekuCoord = new System.Drawing.Point(ImageRat.Deku.PosX, ImageRat.Deku.PosY);      // Create a 'System Point' for Deku
            System.Drawing.Point BakuCoord = new System.Drawing.Point(ImageRat.Bakugo.PosX, ImageRat.Bakugo.PosY);  // Create a 'System Point' for Bakugo


            if (DekuWake == false)
            {
                DekuImage.Hide();
                if (BakuWake == false)
                {
                    BakuImage.Hide();
                    HouseImage.Image = DesktopApp1.Properties.Resources.bothsleep;// set HouseImage to both sleep
                }
                else
                {
                    BakuImage.Location = BakuCoord;
                    Console.WriteLine("Point:" + BakuCoord);
                    //Console.WriteLine("Reaching Relocation condition"); // Ensure we are getting here as animation not working
                    BakuImage.Show();
                    //BakuImage.
                    HouseImage.Image = DesktopApp1.Properties.Resources.dekuSleep; //Set HouseImage to DekuSleep 
                }
            }
            else //DekuWake == true
            {
                DekuImage.Show();
                if (BakuWake == true)
                {
                    HouseImage.Image = DesktopApp1.Properties.Resources.nosleep;//Set House image to nosleep
                    BakuImage.Location = DekuCoord;
                    DekuImage.Show();
                    BakuImage.Location = BakuCoord;
                    BakuImage.Show();
                }    
                else
                {
                    BakuImage.Hide();
                    HouseImage.Image = DesktopApp1.Properties.Resources.bakusleep;// Set house image to bakusleep
                    DekuImage.Location = DekuCoord;
                    DekuImage.Show();
                }
            }

            HouseImage.Show(); // Out here as it should always happen
        }
    }
 }

1 Ответ

0 голосов
/ 23 января 2019

Хорошо, поэтому у меня нет точного ответа, как решить эту проблему, но я могу рассказать вам, почему это происходит, и указать вам некоторые знания, которые помогут вам.

В то время, когда я писал этот код, я был (и до сих пор) очень плохо знаком с C # и концепцией многопоточных приложений в целом.

Это вопрос плохой архитектуры программного обеспечения. Проблема здесь в том, что пользовательский интерфейс может быть обновлен только из одного потока в c #, и, поскольку таймер работает в другом потоке, все, что вызывается из таймера, не может обновлять пользовательский интерфейс. Я думаю, что можно погрузиться в поток пользовательского интерфейса с помощью делегатов, хотя я еще недостаточно углубился в это, чтобы дать вам точную информацию о том, как это делается.

Надеюсь, это поможет людям, которые снялись в моем вопросе! Как обновить графический интерфейс из другого потока?

...