Проблема с обновлением холста в windows форме приложения - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь сделать алгоритм визуализации сортировки в c#, но у меня возникла проблема с обновлением холста.

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

На этом рисунке вы видите черные прямоугольники, которые я хочу удалить с холста

pic

Это мой код:

    private void GenerateArrayButton_Click(object sender, EventArgs e)
    {
        MyCanvas.Refresh();
        Random random = new Random();
        int xPosition = 0 , yPosition = MyCanvas.Height/2; 
        const int k_RectangleWight = 2;

        for(int i = 0; i < k_SizeOfArray; i++)
        {
            int rectangleHeight = random.Next(MyCanvas.Height / 2);
            m_UnsortedArray[i] = new Rectangle(xPosition,yPosition, k_RectangleWight, rectangleHeight);
            xPosition += 5;
        }

        draw(m_UnsortedArray, Pens.Black);

    }

    private void draw(Rectangle[] i_ArrayToDraw, Pen i_PenColor)
    {
        var graphics = MyCanvas.CreateGraphics();
        graphics.DrawRectangles(i_PenColor, i_ArrayToDraw);
        graphics.Dispose();
    }

    private void SortingButton_Click(object sender, EventArgs e)
    {
        bubbleSort();
        draw(m_UnsortedArray, Pens.Green);
    }

    private void bubbleSort()
    {
        for(int i = 0; i < m_UnsortedArray.Length; i++)
        {
            for(int j = 0; j < m_UnsortedArray.Length - 1; j++)
            {
                if(m_UnsortedArray[j].Height > m_UnsortedArray[j + 1].Height)
                {
                    swap(ref m_UnsortedArray[j], ref m_UnsortedArray[j+1]);
                }
            }
            draw(m_UnsortedArray,Pens.Black);
        }
    }

    private void swap(ref Rectangle i_Rectangle1, ref Rectangle i_Rectangle2)
    {
        // Swap the position of the rectangle
        var location = i_Rectangle1.Location;
        i_Rectangle1.Location = i_Rectangle2.Location;
        i_Rectangle2.Location = location;

        // Swap the position of the current rectangle in the array
        var copyRect = i_Rectangle1;
        i_Rectangle1 = i_Rectangle2;
        i_Rectangle2 = copyRect;
    }

}

1 Ответ

0 голосов
/ 27 апреля 2020

Холст для рисования MyCanvas, будь то PictureBox, или Panel, или сама форма, предоставляет определенные c события для процедур рисования, в частности, событие Paint в этом контексте. У события есть PaintEventArgs, который предоставляет бесплатный Graphics объект для выполнения ваших рисунков. То есть вам не нужно создавать дополнительные Graphics объекты, как в вашем draw методе. Теперь давайте нарисуем эти прямоугольники.

Поля уровня класса:

using System.Threading.Tasks;
//...

public partial class Form1 : Form
{
    private const int k_RectangleWight = 2;
    private const int k_SizeOfArray = 100; //assign the right value.

    private Rectangle[] m_UnsortedArray;
    Random rand = new Random();
    private Pen MyPen;

Обработка события Paint элемента управления MyCanvas.

    public Form1()
    {
        InitializeComponent();

        //You can add normal event handler instead if you prefer so.
        MyCanvas.Paint += (s, e) =>
        {
            if (MyPen != null)
                e.Graphics.DrawRectangles(MyPen, m_UnsortedArray);
        };
    }

В событии GenerateArrayButton_Click создайте прямоугольники, назначьте перо для рисования и вызовите метод Invalidate() холста для рисования.

    private void GenerateArrayButton_Click(object sender, EventArgs e)
    {
        m_UnsortedArray = new Rectangle[k_SizeOfArray];
        var xPosition = 0;
        var yPosition = MyCanvas.Height / 2;
        for(var i = 0; i < k_SizeOfArray; i++)
        {
            var rectangleHeight = rand.Next(MyCanvas.Height / 2);
            m_UnsortedArray[i] = new Rectangle(
                xPosition, 
                yPosition, 
                k_RectangleWight, 
                rectangleHeight);
            xPosition += 5;
        }
        MyPen = Pens.Black;
        MyCanvas.Invalidate();
    }

На этом этапе вы получите что-то вроде этого:

SOQ61443730A

Теперь вторая часть. Ваши методы для замены прямоугольников:

    private async void bubbleSort()
    {
        for (int i = 0; i < m_UnsortedArray.Length; i++)
        {
            for (int j = 0; j < m_UnsortedArray.Length - 1; j++)
                if (m_UnsortedArray[j].Height > m_UnsortedArray[j + 1].Height)
                    swap(ref m_UnsortedArray[j], ref m_UnsortedArray[j + 1]);
            await Task.Delay(30);
            MyCanvas.Invalidate();
        }
    }

    private void swap(ref Rectangle i_Rectangle1, ref Rectangle i_Rectangle2)
    {
        var location = i_Rectangle1.Location;
        i_Rectangle1.Location = i_Rectangle2.Location;
        i_Rectangle2.Location = location;

        var copyRect = i_Rectangle1;
        i_Rectangle1 = i_Rectangle2;
        i_Rectangle2 = copyRect;
    }

В случае нажатия SortingButton вам просто нужно:

    private void SortingButton_Click(object sender, EventArgs e)
    {
        MyPen = Pens.Green;
        bubbleSort();
    }
}

... и вы получите:

SOQ61443730C

...