如何重写OnPaint事件?

pro3979 2007-03-24 01:08:21
最新做一个实验,有两个界面form1和temForm,现在遇到两个问题.

问题一:

在temForm中我要做的是一个根据数据库里的数据来绘制出不同颜色的矩形若干个,并且还要保持实时刷新,能从界面上矩形颜色的变化看出数据库数据的变化,在这个界面中我用了一个时钟time1进行每3秒刷新一次temForm,但事实上这个功能并没有实现,绘图我用了双缓冲,图像是绘出来了,可是数据库里的数据在变化,界面却没有实现预期的刷新功能.请大家帮帮忙,如何实现?

有人说重写OnPaint事件就可以,谁能告诉我怎么重写OnPaint事件?
我写的代码在下面:请帮帮忙,我该怎么做,谢谢.

问题二:

在form1中调用temform,让temform得以显示,并且还要实现 问题一 中期望的那样显示,但实际上,temform的界面是显示出来了,可是绘出来的图像只是一闪就没有了,过一会又是一闪又没有了,一直这样直到你关闭窗口.form1中调用temform的代码也在下面,请大家帮帮忙,我该怎么做,谢谢.

以上两个问题答对任何一个均有分.

问题一的代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace temperature
{
public partial class temForm : Form
{
public temForm()
{
InitializeComponent();
}
private void temForm_Load(object sender, EventArgs e)
{
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics buffergraphics = e.Graphics;
Image mybuffer = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
Graphics g = Graphics.FromImage(mybuffer);

SqlConnection thisconnection = new SqlConnection(@"Data Source=(local);Initial Catalog=experiment;Integrated Security=True");
thisconnection.Open();
g.FillRectangle(Brushes.White, ClientRectangle);
int i;
int j;
double m;
Brush colorflag = Brushes.White;
for (i = 10; i <= 300; i += 13)
{
for (j = 20; j <= 500; j += 16)
{
SqlCommand thiscommand = thisconnection.CreateCommand();
thiscommand.CommandText = "select data from exp3 where x=" + i + " and y=" + j + " ";
SqlDataReader thisreader = thiscommand.ExecuteReader();
while (thisreader.Read())
{
m = Convert.ToDouble(thisreader["data"]);
if (m < 50)
{ colorflag = Brushes.Lime; }
else if (m >= 50 & m < 70)
{ colorflag = Brushes.SpringGreen; }
else if (m >= 70 & m < 90)
{ colorflag = Brushes.PaleGreen; }
else if (m >= 90 )
{ colorflag = Brushes.SeaGreen; }
}
g.FillRectangle(colorflag, new Rectangle(i, j, 10, 10));
thisreader.Close();
}
}
buffergraphics.DrawImage(mybuffer, ClientRectangle);
mybuffer.Dispose();
}
private void timer1_Tick(object sender, EventArgs e)
{
this.Invalidate();
} } }


问题二的代码如下:

private void temperaturemenu_Click(object sender, EventArgs e)
{
temperature tempfrm = new temperature();
try
{
tempfrm.ShowDialog();
}
finally
{
tempfrm.Dispose();
}
}

如何重写OnPaint事件?
...全文
554 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaobailong3979 2007-03-24
  • 打赏
  • 举报
回复
应该是这样的
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Xml;



namespace temperature
{
public partial class temForm : Form
{
public temForm()
{
InitializeComponent();

Timer timer = new Timer();
timer.Enabled = true;
timer.Interval = 3000;
timer.Tick += new EventHandler(timer_Tick);

}

SqlConnection thisconnection = new SqlConnection(@"Data Source=(local);Initial Catalog=experiment;Integrated

Security=True");

private void temForm_Load(object sender, EventArgs e)
{
thisconnection.Open();
}

void timer_Tick(object sender, EventArgs e)
{
this.paintTemp(this.ClientRectangle);
}


protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
this.drawTemp(e.Graphics, e.ClipRectangle);
}


protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
this.paintTemp(this.ClientRectangle);
}
private void drawTemp(Graphics g, Rectangle rectangle)
{
int i;
int j;
double m;

Brush colorflag = Brushes.White;


for (i = 60; i <= 918; i += 13)
{
for (j = 100; j <= 628; j += 16)
{

SqlCommand thiscommand = thisconnection.CreateCommand();
thiscommand.CommandText = "select data from exp3 where x=" + (((i - 50) / 13) + 1) + " and y=" +(((628 -

j) / 16) + 1) + " ";

SqlDataReader thisreader = thiscommand.ExecuteReader();

while (thisreader.Read())
{
m = Convert.ToDouble(thisreader["data"]);

if (m < 50)

{ colorflag = Brushes.Lime; }

else if (m >= 50 & m < 70)
{ colorflag = Brushes.SpringGreen; }

else if (m >= 70 & m < 90)
{ colorflag = Brushes.PaleGreen; }

else if (m >= 90 )
{ colorflag = Brushes.SeaGreen; }
}
g.FillRectangle(colorflag, new Rectangle(i, j, 10, 10));
thisreader.Close();
}
}
}
internal void paintTemp(Rectangle rect)
{
if (!this.IsDisposed && this.Visible)
{
BufferedGraphicsContext myContext = BufferedGraphicsManager.Current;
BufferedGraphics buffer = myContext.Allocate(this.CreateGraphics(), rect);
if (buffer.Graphics != null)
{
buffer.Graphics.Clear(this.BackColor);
this.drawTemp(buffer.Graphics, this.ClientRectangle);
}
buffer.Render();
buffer.Dispose();
}
}
}
}


pro3979 2007-03-24
  • 打赏
  • 举报
回复
hbxtlhx(平民百姓)

大哥,你给的这个实例我有点看不懂啊.我也是才刚开始学C#的,要做的这个东西时间又比较赶,你可不可以告诉我在time1_Tick里应该怎么写才能实现定时刷新啊,而且还要画面不会闪动啊,就是说如果一个矩形颜色要变化,只要它变化,其它的没有任何变化.拜托你了.感激不尽!很着急,希望你能帮我.谢了.!
北京的雾霾天 2007-03-24
  • 打赏
  • 举报
回复
给你一个实时绘制的代码看一下吧,你的问题我不好直接的回答:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace DoubleBufferDraw
{
public partial class clock : Form
{
public clock()
{
InitializeComponent();
Timer timer = new Timer();
timer.Enabled = true;
timer.Interval = 100;
timer.Tick += new EventHandler(timer_Tick);
}

void timer_Tick(object sender, EventArgs e)
{
this.paintClock(this.ClientRectangle);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
this.drawClock(e.Graphics, e.ClipRectangle);
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
this.paintClock(this.ClientRectangle);
}
private void drawClock(Graphics g, Rectangle rectangle)
{
SolidBrush brush1 = new SolidBrush(Color.SteelBlue);
SolidBrush brush2 = new SolidBrush(Color.SkyBlue);
SolidBrush brush3 = new SolidBrush(Color.Teal);
SolidBrush brush4 = new SolidBrush(Color.Teal);
SolidBrush brush5 = new SolidBrush(Color.Black);
Pen pen1 = new Pen(brush1, 2.0f); //"时点"画笔
Pen pen2 = new Pen(brush2, 1.5f); //"分点"画笔
Pen pen3 = new Pen(brush3, 0.2f); //"时针"画笔
Pen pen4 = new Pen(brush4, 0.2f); //"分针"画笔
Pen pen5 = new Pen(brush5, 1); //"秒针"画笔
Point center = new Point(this.ClientRectangle.Left + this.ClientRectangle.Width / 2, this.ClientRectangle.Top + this.ClientRectangle.Height / 2);
//画表盘
for (int i = 1; i <= 60; i++)
{
if (i % 5 == 0)
g.DrawEllipse(pen1, center.X + (int)(Math.Cos(Math.PI / 180 * i * 6) * 60), center.Y + (int)(Math.Sin(Math.PI / 180 * i * 6) * 60), 2.0f, 2.0f);
else
g.DrawEllipse(pen2, center.X + (int)(Math.Cos(Math.PI / 180 * i * 6) * 60), center.Y + (int)(Math.Sin(Math.PI / 180 * i * 6) * 60), 1.5f, 1.5f);
}
//画时针
Point ph = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * ((DateTime.Now.Hour - 3) * 30 + DateTime.Now.Minute / 12 * 6)) * 40), center.Y + (int)(Math.Sin(Math.PI / 180 * ((DateTime.Now.Hour - 3) * 30 + DateTime.Now.Minute / 12 * 6)) * 40));
Point phl = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * ((DateTime.Now.Hour + 3) * 30 + DateTime.Now.Minute / 12 * 6)) * 7), center.Y + (int)(Math.Sin(Math.PI / 180 * ((DateTime.Now.Hour + 3) * 30 + DateTime.Now.Minute / 12 * 6)) * 7));
Point pch1 = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * ((DateTime.Now.Hour) * 30 + DateTime.Now.Minute / 12 * 6)) * -5), center.Y + (int)(Math.Sin(Math.PI / 180 * ((DateTime.Now.Hour) * 30 + DateTime.Now.Minute / 12 * 6)) * -5));
Point pch2 = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * ((DateTime.Now.Hour) * 30 + DateTime.Now.Minute / 12 * 6)) * 5), center.Y + (int)(Math.Sin(Math.PI / 180 * ((DateTime.Now.Hour) * 30 + DateTime.Now.Minute / 12 * 6)) * 5));
g.FillPolygon(brush1, new Point[] { ph, pch1, phl, pch2 });
//画分针
Point pm = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * (DateTime.Now.Minute - 15) * 6) * 48), center.Y + (int)(Math.Sin(Math.PI / 180 * (DateTime.Now.Minute - 15) * 6) * 48));
Point pml = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * (DateTime.Now.Minute + 15) * 6) * 9), center.Y + (int)(Math.Sin(Math.PI / 180 * (DateTime.Now.Minute + 15) * 6) * 9));
Point pcm1 = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * (DateTime.Now.Minute) * 6) * -4), center.Y + (int)(Math.Sin(Math.PI / 180 * (DateTime.Now.Minute) * 6) * -4));
Point pcm2 = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * (DateTime.Now.Minute) * 6) * 4), center.Y + (int)(Math.Sin(Math.PI / 180 * (DateTime.Now.Minute) * 6) * 4));
g.FillPolygon(brush1, new Point[] { pm, pcm1, pml, pcm2 });
//画秒针
Point pc = new Point(center.X, center.Y);
Point ps = new Point(center.X + (int)(Math.Cos(Math.PI / 180 * (DateTime.Now.Second - 15) * 6) * 48), center.Y + (int)(Math.Sin(Math.PI / 180 * (DateTime.Now.Second - 15) * 6) * 48));
g.DrawLine(pen5, pc, ps);
}
internal void paintClock(Rectangle rect)
{
if (!this.IsDisposed && this.Visible)
{
BufferedGraphicsContext myContext = BufferedGraphicsManager.Current;
BufferedGraphics buffer = myContext.Allocate(this.CreateGraphics(), rect);
if (buffer.Graphics != null)
{
buffer.Graphics.Clear(this.BackColor);
this.drawClock(buffer.Graphics, this.ClientRectangle);
}
buffer.Render();
buffer.Dispose();
}
}
}
}
pro3979 2007-03-24
  • 打赏
  • 举报
回复
hbxtlhx(平民百姓)

朋友,可不可以告诉我具体怎么做啊?我是新手,很多东西还不懂,麻烦你告诉我一下好吗?谢谢了.
he_8134 2007-03-24
  • 打赏
  • 举报
回复
1,2楼都正解~~~OnPaint是界面重绘的时候调用的,重绘可是一秒钟不知道执行几次呢~~~
北京的雾霾天 2007-03-24
  • 打赏
  • 举报
回复
不要在Paint事件里处理数据库的操作,这样的事件发生的次数可能太多,这样程序的效率太差!

最好在private void timer1_Tick(object sender, EventArgs e)
里用Graphics g = this.CreateGraphics()
来建立画图对象把数据从数据库取出进行绘制,而不是用Invalidate来要求重绘,是主动去绘制.

你这个问题如果单纯的用OnPaint方法来处理的话反而不太好,可能发生局部内容不一样,所以把画的代码放到Timer里最合适,而是在OnPaint方法里对现有的数据绘制而不是在OnPaint方法里再去数据库取.
Jinwmmail 2007-03-24
  • 打赏
  • 举报
回复

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc=e.Graphics;

........

dc.Draw.....


}

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧