Question

Imagine a simple .Net 2.0 Windows-Form with a MultilineTextbox that fills the whole form. I want to (re-)draw a rectangle everytime a key is pressed. In the real application there is fare more logic about the position and stuff of the rectangle - but keep it simple.

I thought: "Lets first invalidate the TextBox and then draw the rectangle." But this doesnt work. The screen flickers shortly - thats it. If I remove the line "invaliate" a rectangle is drawn - but the old ones keep their position..

Whats wrong? And how do I repaint from scratch?

Thank you in advance for your answers!

private void OnKeyDown(object sender, KeyEventArgs e)
{
        textBox1.Invalidate();

        using (Graphics g = this.textBox1.CreateGraphics())
        {
            int startX = 100;
            int startY = 300;
            int height = 200;

            Brush brush = new SolidBrush(Color.FromArgb(60, 255, 0, 0));

            Pen myPen = new Pen(Color.Black, 2);
            myPen.DashStyle = DashStyle.Dash;

            g.DrawRectangle(myPen, startX, startY, this.textBox1.Width, height);

            g.FillRectangle(brush, startX, startY, this.textBox1.Width, height);
        }
}
Était-ce utile?

La solution 3

I was told to use "textBox1.Refresh()" instead of "textBox1.Invalidate();" and it works!

private void OnKeyDown(object sender, KeyEventArgs e)
{
    //textBox1.Invalidate(); - Dont do that
    textBox1.Refresh(); //Dominik Schelenz, my internet Hero for today!

    using (Graphics g = this.textBox1.CreateGraphics())
    {
        int startX = 100;
        int startY = 300;
        int height = 200;

        Brush brush = new SolidBrush(Color.FromArgb(60, 255, 0, 0));

        Pen myPen = new Pen(Color.Black, 2);
        myPen.DashStyle = DashStyle.Dash;

        g.DrawRectangle(myPen, startX, startY, this.textBox1.Width, height);

        g.FillRectangle(brush, startX, startY, this.textBox1.Width, height);
    }
}

Autres conseils

Your approach is flawed. Invalidate() only requests a repaint but it is delayed and happens after you draw the rectangle. So it disappears again immediately.

A short (but wrong) fix would be to replace Invalidate() with Update(), but don't do that.

You'll have to move the drawing logic to the textBox1.Paint event. And your form needs a (boolean) property to decide whether to draw the Rectangle or not.

Your KeyDown should look like:

private void OnKeyDown(object sender, KeyEventArgs e)
{
    this.DrawRect = true;
    textBox1.Invalidate();
}

Call this.Invalidate(); on keypress, and move your drawing code to the OnPaint event where it is supposed to go. If you want to completely avoid flicker, you need to draw according to the following guide: C#, double buffer in WinForms?.

You should also keep a List<> of all you rects and draw each one OnPaint as your key press is not the only thing that can invalidate the form and cause a redraw.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top