当我重绘和绘制形状Winforms时,窗体闪烁 [英] Form Is Flickering While I Redrawing And Drawing Shapes 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> ofOnPaint
。
修复它,并且,更改是,它将适用于您。也许你犯了其他一些错误,但我现在看不到任何错误。
顺便说一下,这只是愚蠢的:
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 usingGraphics rectangledraw = m_canavs.CreateGraphics()
. You should not do it. Instead, you should use the instance oCanvas
passed to you through the argumentPaintEventArgs e
ofOnPaint
.
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屋!