вызов draw rect иногда ничего не делает - PullRequest
0 голосов
/ 17 июня 2020
• 1000 он печатает «yo», но не вносит изменений в форму

здесь я инициализирую свою форму, вызываю свою функцию и рисую на экране 1 поле.

    public Form1()
    {
        InitializeComponent();
        draw_rect(this, 50, 150, 20, 20, 0); // draw a first black box
        this.Shown += (s, e) =>
        {
            Task.Run(() =>
            {
                draw_forever();
            }
        );};}

это 1 поле i рисовать - это все, что вы когда-либо видели. поэтому мы можем видеть, что он никогда не очищает экран с белым квадратом

image

скопируйте и вставьте приведенный ниже код в пустую форму c#, чтобы быстро скопировать что я сделал

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

namespace draw_forev
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            draw_rect(this, 50, 150, 20, 20, 0); // draw a first black box
            this.Shown += (s, e) =>
            {
                Task.Run(() =>
                {
                    draw_forever();
                }
            );
            };
        }
        public static void draw_rect(Form form, int x, int y, int width, int height, int colournum) // this function draws a block
        {
            Color thecolour;
            if (colournum == 0) { thecolour = Color.Black; }
            if (colournum == 1) { thecolour = Color.White; }
            form.Paint += OnPaint;
            void OnPaint(object sender, PaintEventArgs e)
            {
                if (colournum == 0)
                {
                    using (var Pen1 = new Pen(Color.Black, 9))
                    {
                        e.Graphics.DrawRectangle(Pen1, x, y, width, height);
                    }
                }
                if (colournum == 1)
                {
                    using (var Pen1 = new Pen(Color.White, 9))
                    {
                        Rectangle rect = new Rectangle(x, y, width, height);
                        e.Graphics.DrawRectangle(Pen1, rect);
                    }
                }
            }
        }

        public void draw_forever() {
            int counter = 0;
            while (1 < 2) {
                counter += 1;
                Debug.WriteLine("yo");
                draw_rect(this, 0, 0, this.Width, this.Height, 1); // create a white box to clear the screen 
                draw_rect(this, counter, 150, 20, 20,0); // create a black box that moves accross the screen 
                if (counter > this.Width) { counter = 0; } // reset the box 
            }
        }


    }
}

1 Ответ

0 голосов
/ 17 июня 2020

Я внес некоторые изменения в ваш код:

Сначала я сделал метод draw_forever asyn c, поэтому вы можете использовать await Task.Delay(55). Если вы не используете это, вы ничего не увидите, потому что ваша форма постоянно обновляется.

Затем вам нужно обновить метод draw_rect. Вы рисуете только контур прямоугольника, который не очищает экран. Также я бы порекомендовал вам заменить целочисленное значение colournum фактическим параметром Color. Это упрощает метод draw_rect и делает код более читабельным.

Третье изменение - вам нужно обновить форму. Введите this.Refresh(), чтобы убедиться, что все изменения будут отображены.

Вот новый код:

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

namespace draw_forev
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            draw_rect(this, 50, 150, 20, 20, Color.Black, false); // draw a first black box
            this.Shown += (s, e) =>
            {
                Task.Run(() =>
                {
                    draw_forever();
                }
            );
            };
        }
        public static void draw_rect(Form form, int x, int y, int width, int height, Color colour, bool fill) // this function draws a block
        {
            form.Paint += OnPaint;
            void OnPaint(object sender, PaintEventArgs e)
            {
                if (fill)
                {
                    e.Graphics.FillRectangle(new SolidBrush(colour), x, y, width, height);
                }
                else
                {
                    e.Graphics.DrawRectangle(new Pen(colour, 9), x, y, width, height);
                }
            }
        }

        public async void draw_forever()
        {
            int counter = 0;
            while (1 < 2)
            {
                counter += 1;
                Debug.WriteLine("yo " + counter);
                draw_rect(this, 0, 0, this.Width, this.Height, Color.White, true); // create a white box to clear the screen 
                draw_rect(this, counter, 150, 20, 20, Color.Black, false); // create a black box that moves accross the screen 
                this.Invoke(new MethodInvoker(this.Refresh));
                if (counter > this.Width)
                { counter = 0; } // reset the box 
                await Task.Delay(55);
            }
        }


    }
}

Несмотря на то, что этот код работает, он совсем не эффективен. Вы должны подписаться на событие OnPaint только один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...