如何在表格的特定部分重画/更新

时间:2018-10-13 08:29:33

标签: c#

基本上,我试图在线条帮助下可视化冒泡排序算法。我是图形新手。我能够产生随机和垂直的线条,并按升序对其进行排序,并显示已排序和未排序的线条。我试图可视化交换过程,但是每当我尝试更新表单时,它都会从头开始重新绘制所有内容,甚至不更新屏幕上的任何内容。但是当我调用Update()时;排序后的功能我可以看到它已排序。 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();
    }
}

编辑:现在对气泡排序添加了延迟,我可以看到它重新绘制和排序,但问题仍然在于它再次重新绘制了所有点。

1 个答案:

答案 0 :(得分:1)

不确定您的期望,但这确实很有趣:

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();
}

排序本身保持不变(从原始帖子开始!),仅移动了更新触发器:

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
    }
}

Paint应该显示当前状态,而不是调用排序:

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);
    }
}

注释:

  • 如果我们在循环的更深处触发Paint,事情会变得缓慢
  • 如果我们使用Invalidate(通常是更新图形的推荐方法),则构建过程将是瞬时的。
  • 另外:请在Double-Buffering上打开Form以避免闪烁!