Danial Ahmed
Danial Ahmed

Reputation: 866

How to redraw/update on particular portion of Form

Basically I was trying to visualize Bubble Sort Algorithm with help of lines. I am new with Graphics. I am able to produce random and vertical lines and sort them in ascending order and display both sorted and unsorted lines. I am trying to visualize the swap process but when ever I try to update the form it redraws everything from scratch and dont even update anything on screen. But when i call the Update(); function after sorting I can see it is sorted. Unsorted

Sorted

private float[] values;
private int m=0;
public Form1()
{
    InitializeComponent();
    values =new float[Width];
}

private void Form1_Load(object sender, EventArgs e)
{
    Random rnd = new Random();
    for (int i = 0; i < values.Length; i++)
    {
        values[i] = rnd.Next(Height);
    }
}
void bubbleSort()
{
    Task.Run(async () =>
    {
        for (m = 0; m < values.Length; m++)
        {
            for (int j = 0; j < values.Length - m - 1; j++)
            {
                if (values[j] > values[j + 1])
                {
                    float temp = values[j];
                    values[j] = values[j + 1];
                    values[j + 1] = temp;
                    Invalidate();
                }
            }
            await Task.Delay(1000);
        }
    });
    //Update();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
    //var graphicsObj = this.CreateGraphics();

    Pen blackPen = new Pen(Color.Black, (float)0.5);

    for (int i = 0; i < values.Length; i++)
    {
            e.Graphics.DrawLine(blackPen, i, 0, i, values[i]);
    }
    if (m<values.Length)
    {
        bubbleSort();
    }
}

EDIT: Added Delay to bubble sort now I can see it redrawing and sorting but still the problem is that it redraws all of the points again.

Upvotes: 0

Views: 51

Answers (1)

TaW
TaW

Reputation: 54433

Not sure what you expect, but this does look interesting:

enter image description here

float[] values =new float[555];
int m=0;

private void startButton_Click(object sender, EventArgs e)
{
    Random rnd = new Random();
    for (int i = 0; i < values.Length; i++)
    {
        values[i] = rnd.Next(Height);
    }
    m=0;
    bubbleSort();
}

The sort itself is unchanged (from the original post!), just the update trigger is moved:

void bubbleSort()
{
    for (m = 0; m < values.Length; m++)
    {
        for (int j = 0; j < values.Length - m - 1; j++)
        {
            if (values[j] > values[j + 1])
            {
                float temp = values[j];
                values[j] = values[j + 1];
                values[j + 1] = temp;
            }
        }
        Refresh();   // Invalidate would be optimized away
    }
}

The Paint should show the current state and not call the sort:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    for (int i = 0; i < values.Length; i++)
    {
        e.Graphics.DrawLine(Pens.Black, i, 0, i, values[i]);
        e.Graphics.DrawLine(Pens.White, i,  values[i], i, ClientSize.Height);
    }
}

Notes:

  • If we trigger Paint deeper inside the loop, things get painfully slow.
  • If we use Invalidate, usually the recommended way to update graphics, the build-up would be instantaneous.
  • Also: Do turn on Double-Buffering on the Form to avoid flicker!

Upvotes: 1

Related Questions