当我重绘和绘制形状Winforms时,窗体闪烁 [英] Form Is Flickering While I Redrawing And Drawing Shapes Winforms

查看:81
本文介绍了当我重绘和绘制形状Winforms时,窗体闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在中尝试 绘制一个椭圆带有鼠标事件,
鼠标 时down,移动 我的代码喜欢这个:





  void  panel1_MouseDown( object  sender,MouseEventArgs e)
{
startpoint.X = eX;
startpoint.Y = e.Y;

if (m_drawrectiangle == true
{
m_shape = new Rectiangle( 0 0 this );
m_shape.Xpos = e.X;
m_shape.Ypos = e.Y;
draw = true ;
}
如果(m_draweliipse == true
{
m_shape = new Circle( 0 0 );
m_shape.Xpos = e.X;
m_shape.Ypos = e.Y;
draw = true ;

}

}
void panel1_MouseUp( object sender,MouseEventArgs e)
{

if (m_shape!= null
{
if (m_shape.Area()== 0
{
this .Cursor = Cursors.Default;
draw = false ;
}
如果(draw == true
{
shapes.Add(m_shape);
this .Cursor = Cursors.Default;
draw = false ;
Invalidate();
}
}
}
void panel1_MouseMove( object sender,MouseEventArgs e)
{

this .Text = + eX + + eY + ;

if (draw == true && m_drawrectiangle == < span class =code-keyword> true )
{
int x =(eX < 0 )? 0 :e.X;
int y =(eY < 0 )? 0 :e.Y;

// 切换位置
m_shape.Xpos =(x < startpoint.X)? x:startpoint.X;
m_shape.Ypos =(y < startpoint.Y)? y:startpoint.Y;

((Rectiangle)m_shape).Width = Math.Abs​​(x - startpoint.X);
((Rectiangle)m_shape).Height = Math.Abs​​(y - startpoint.Y);


Invalidate(); // 重新绘制
}
if (draw == true && m_draweliipse == true
{
int x =(eX < 0 )? 0 :e.X;
int y =(eY < 0 )? 0 :e.Y;

// 切换位置
m_shape.Xpos =(x < startpoint.X)? x:startpoint.X;
m_shape.Ypos =(y < startpoint.Y)? y:startpoint.Y;
double deltax = Math.Pow(x-startpoint.X, 2 );
double deltay = Math.Pow(y-startpoint.Y, 2 );
((Circle)m_shape).Diam =( decimal )Math.Sqrt(deltax + deltay); / / 类型转换安全
Invalidate(); // 重新绘制

}
}



我的主要问题是当我在列表中保存圆圈或rectinagle时,每次我绘制一个新的圆圈/整形时,列表中的形状闪烁...这里是我的Onpaint事件:

 受保护 覆盖  void  OnPaint(PaintEventArgs e)
{

if (draw == < span class =code-keyword> true )
{
m_shape.draw();
}
如果(shapes.Count > 0
{
foreach (形成 shapes)
{
a.draw();
if (m_drawarea == true
{
string text1 = a.Area()。ToString( 0。 00\" );
Font font1 = new 字体( Arial 8 ,FontStyle.Bold,GraphicsUnit.Point);
使用(Graphics rectangledraw = CreateGraphics())
{
rectangledraw.DrawString(text1,font1,Brushes.Blue,(< span class =code-keyword> float
)a.Xpos,( float )a.Ypos);

}
}

}
}





这里也是我的圈子类绘制部分:

  public  覆盖  void  draw()
{
使用( Graphics rectangledraw = m_canavs.CreateGraphics())
{
RectangleF rectF1 = new RectangleF(Xpos,Ypos,( float m_diam,( float )m_diam);
rectangledraw.DrawEllipse( new Pen(Color.Black, 2 ),Rectangle.Round( rectF1));
}
}
}
}



有谁可以告诉我我做错了什么?因为我不知道该怎么做?

双倍缓冲只会让它变得更糟...

解决方案

使用double可以防止闪烁缓冲: http:// msdn。 microsoft.com/en-us/library/system.windows.forms.control.doublebuffered%28v=vs.110%29.aspx [ ^ ]。



你明白为什么吗?应该很明显。



你是说双缓冲只会让它变得更糟吗?它不应该。但是,正如我所看到的,你做错了。完全错了。你的主要错误是使用 Graphics rectangledraw = m_canavs.CreateGraphics()你不应该这样做。相反,你应该使用通过参数 PaintEventArgs e <传递给你的实例o Canvas / code> of OnPaint



修复它,并且,更改是,它将适用于您。也许你犯了其他一些错误,但我现在看不到任何错误。



顺便说一下,这只是愚蠢的:

  if (draw ==  true && m_drawrectiangle ==  true  //   ...  



这与

 如果(draw& ;& m_drawrectiangle) //   ...  



不,问题不是缩短代码,问题是缺乏对你检查的内容和布尔角色的理解。



- SA

i trying in winforms to draw an ellipse with mouse event ,
when mouse is down ,move and up my code goes like this :



   void panel1_MouseDown(object sender, MouseEventArgs e)
{
    startpoint.X = e.X;
    startpoint.Y = e.Y;

    if (m_drawrectiangle == true)
    {
        m_shape = new Rectiangle(0, 0, this);
        m_shape.Xpos = e.X;
        m_shape.Ypos = e.Y;
        draw = true;
    }
        if (m_draweliipse == true)
        {
            m_shape = new Circle(0, 0, this);
            m_shape.Xpos = e.X;
            m_shape.Ypos = e.Y;
            draw = true;

        }

}
void panel1_MouseUp(object sender, MouseEventArgs e)
{

    if (m_shape != null)
    {
        if(m_shape.Area()==0)
        {
            this.Cursor = Cursors.Default;
            draw = false;
        }
        if (draw == true)
        {
            shapes.Add(m_shape);
            this.Cursor = Cursors.Default;
            draw = false;
            Invalidate();
        }
    }
}
void panel1_MouseMove(object sender, MouseEventArgs e)
{

    this.Text = "(" + e.X + ", " + e.Y + ")";

    if (draw==true  && m_drawrectiangle==true )
    {
        int x = (e.X < 0) ? 0 : e.X;
        int y = (e.Y < 0) ? 0 : e.Y;

        //switch places
        m_shape.Xpos = (x < startpoint.X) ? x : startpoint.X;
        m_shape.Ypos = (y < startpoint.Y) ? y : startpoint.Y;

       ( (Rectiangle)m_shape).Width = Math.Abs(x - startpoint.X);
      ( (Rectiangle) m_shape).Height = Math.Abs(y - startpoint.Y);


        Invalidate(); //re-paint
    }
    if ( draw==true && m_draweliipse==true )
    {
        int x = (e.X < 0) ? 0 : e.X;
        int y = (e.Y < 0) ? 0 : e.Y;

        //switch places
        m_shape.Xpos = (x < startpoint.X) ? x : startpoint.X;
        m_shape.Ypos = (y < startpoint.Y) ? y : startpoint.Y;
    double deltax=Math.Pow(x-startpoint.X,2);
    double deltay=Math.Pow(y-startpoint.Y,2);
    ((Circle)m_shape).Diam =(decimal)Math.Sqrt(deltax +deltay);//typecast safe
        Invalidate(); //re-paint

    }
}


my main problem is that when i save the circle or rectinagle in the list, everytime i drawing a new circle/rectiangle ,the shape in the list Flickering... here my Onpaint event:

protected override void OnPaint(PaintEventArgs e)
{

    if(draw==true)
    {
        m_shape.draw();
    }
    if (shapes.Count > 0)
    {
        foreach (shape a in shapes)
        {
            a.draw();
            if (m_drawarea == true)
            {
                string text1 = a.Area().ToString("0. 00");
                Font font1 = new Font("Arial", 8, FontStyle.Bold, GraphicsUnit.Point);
                using (Graphics rectangledraw = CreateGraphics())
                {
                    rectangledraw.DrawString(text1, font1, Brushes.Blue, (float)a.Xpos, (float)a.Ypos);

                }
            }

        }
    }



also here is my circle class the draw part:

   public override void draw()
        {
            using (Graphics rectangledraw = m_canavs.CreateGraphics())
            {
                RectangleF rectF1 = new RectangleF(Xpos, Ypos ,(float)m_diam, (float)m_diam);
                rectangledraw.DrawEllipse(new Pen(Color.Black,2),Rectangle.Round(rectF1));
            }
        }
    }
}


can anybody tell me what i am doing wrong ? because i have no idea what to do?
also doublebuffer only get it worse...

解决方案

Flickering can be prevented by using double buffering: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered%28v=vs.110%29.aspx[^].

Do you understand why? Should be pretty obvious.

Are you saying that double buffering only makes it worse? It should not. But, as I can see, you do it wrong. Totally wrong. Your main mistake is using Graphics rectangledraw = m_canavs.CreateGraphics(). You should not do it. Instead, you should use the instance o Canvas passed to you through the argument PaintEventArgs e of OnPaint.

Fix it, and, changes are, it will work for you. Maybe you made some other mistakes, but I cannot see any right now.

By the way, this is just silly:

if (draw==true  && m_drawrectiangle==true ) //...


This is the same as

if (draw && m_drawrectiangle) //...


No, the problem is not making code shorter, the problem is lack of understanding of what you are checking and the role of Boolean.

—SA


这篇关于当我重绘和绘制形状Winforms时,窗体闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆