GDI+ 绘图 图形移动、刷新 问题,高手请指点

shamohai5566 2010-09-10 03:02:58
我用graphics在groupbox中画了一个单坐标轴(X轴),坐标轴表示的是从0-100%,我想用一个垂直走向的线段指示当前示数(比如说当前值为Value),我现在的做法是每修改一次Value的值,都要调用graphics.clear()清除上一次画的图像,然后重新画。这样一来在清除线段的同时就连坐标轴一起清空了,所以没更改一次Value值我就得连坐标轴和线段都重画。效率很低有没有好的方法,望高手指点...
...全文
818 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
shamohai5566 2010-09-14
  • 打赏
  • 举报
回复
谢谢大家的帮助,我的问题解决了。感谢各位
dylike 2010-09-13
  • 打赏
  • 举报
回复
自定义控件.refresh
shamohai5566 2010-09-13
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 glest 的回复:]
给自定义控件定义个属性:

public PictrueBox PicBox
{
get;set;
}
[/Quote]
定义属性我是会的,但是没有事件,我想当属性值发生变化的时候让它自动触发调用pictureBox1.Invalidate();这里的PictrueBox在我的自定义控件中,而是在Form中 与该自定义控件是平等的层次关系。请问如何实现?
glest 2010-09-11
  • 打赏
  • 举报
回复
给自定义控件定义个属性:

public PictrueBox PicBox
{
get;set;
}

shamohai5566 2010-09-11
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 glest 的回复:]
调用pictureBox1_Paint完成图像更新?
这样不是更好吗?

C# code
pictureBox1.Invalidate();


把pictureBox1传给你的自定义控件。
[/Quote]你好,但是怎么把pictureBox1传给我的自定义控件呀?我手头上没有资料,高手讲的详细点,谢谢
glest 2010-09-11
  • 打赏
  • 举报
回复
调用pictureBox1_Paint完成图像更新?
这样不是更好吗?
pictureBox1.Invalidate();


把pictureBox1传给你的自定义控件。
shamohai5566 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 glest 的回复:]
其实这个程序完全重画也不会很慢的,我给你改了下:

C# code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
……
[/Quote]临书涕零啊!太让我感动了,十分感谢你所做的这些。但是,我刚刚明白我的程序为什么会出现那种效果了,因为在Groupbox中还有好多其它的空间,groupbox重绘时其它控件也要重绘。并不是着段绘图的代码直接造成的。所以我把绘图区域从groupbox分离出来了,我用了一个pictureBox控件,这样一来当TextBox5中内容更新时,调用pictureBox1_Paint完成图像更新。忘了说了,这个TextBox5是我自定义的一个控件中的一个TextBox所以不能直接调用pictureBox1_Paint,我在将pictureBox1_Paint声明为static了但是还是不行,提示“无法使用实例引用来访问成员“NETTEST.Form_Main.pictureBox1_Paint(object, System.Windows.Forms.PaintEventArgs)”;请改用类型名来限定它” 请问这是什么原因呀,要怎么解决,谢谢帮忙,我的分给的太少了,不好意思
glest 2010-09-10
  • 打赏
  • 举报
回复
其实这个程序完全重画也不会很慢的,我给你改了下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Paint
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

int x1=10;
int max = 600;
public void GrahpicsUpdate(Graphics graphics)
{
Pen mypen = new Pen(Color.Black);
Pen mypen1 = new Pen(Color.Red);
System.Drawing.Font font = new System.Drawing.Font("Arial", 8, FontStyle.Regular);
graphics.DrawLine(mypen, 0, 192, 700, 192);
String[] n = { "0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%" };
int xstart = 10;
for (int i = 0; i < 11; i++)
{
graphics.DrawString(n[i].ToString(), font, Brushes.DarkGray, xstart - 7, 192);//.Red
int Xmin = xstart;
for (int j = 0; j < 9; j++)
{
Xmin += 6;
if (j == 4) graphics.DrawLine(mypen, Xmin, 184, Xmin, 192);
else graphics.DrawLine(mypen, Xmin, 188, Xmin, 192);
}
graphics.DrawLine(mypen, xstart, 182, xstart, 192);
xstart = xstart + 60;
}
graphics.DrawLine(mypen1, x1, 180, x1, 200);
}

private void groupBox2_Paint(object sender, PaintEventArgs e)
{
GrahpicsUpdate(e.Graphics);
}

private void textBox5_TextChanged(object sender, EventArgs e)
{
double d = Convert.ToDouble(textBoxPresentVal.Text);
x1 = (int)(d / 100 * max)+10;
groupBox1.Invalidate(); //这里可以传入要更新的区域,不过我觉得没有必要,反而破坏了算法的简洁性,如果不是刻意地追求效率
}
}
}
shamohai5566 2010-09-10
  • 打赏
  • 举报
回复
好的 谢谢 我先看看
crackdung 2010-09-10
  • 打赏
  • 举报
回复
我不知道国内的编程水平怎样,别人的一个3D效果的DLL也只不过2-3m,但是功能和效果及速度都很好,你可以看看

网站



我们的水平和国外还是差很远。


my blog
http://ufo-crackerx.blog.163.com/
dylike 2010-09-10
  • 打赏
  • 举报
回复
form_load()
picturebox1.backgroundimage=c:\坐标轴.bmp



drawvalue()
picturebox1.invaldate()
....
g.drawlines(...
yukunhu 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 shamohai5566 的回复:]
引用 5 楼 yukunhu 的回复:
我试着解释下一楼的意思,比较你画好一个底图存为一个bmp或者别的格式,放在本地资源上,上面的坐标轴已经画好了,你下次把图清掉后,可一在把这个图load到picturebox上,再在上面画图,可能会轻松点,或者直接用这个图作为backgroudimage,前图透明来重绘,不知道这个方法可可行,应该就是这个思路。

你好,我发现我是直接将坐标轴画在了,gr……
[/Quote]直接绘图应该比你自己画的效率高,少了计算。
qqrto 2010-09-10
  • 打赏
  • 举报
回复
我有个想法,你可以用在panel上面添加你的groupbox,然后把坐标轴画到panel上,并设置groupbox的背景色为透明,groupbox.backColor=Color.TransParent,然后再在groupbox上画你的东西,不一定能行,希望能帮上楼主
shamohai5566 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 yukunhu 的回复:]
我试着解释下一楼的意思,比较你画好一个底图存为一个bmp或者别的格式,放在本地资源上,上面的坐标轴已经画好了,你下次把图清掉后,可一在把这个图load到picturebox上,再在上面画图,可能会轻松点,或者直接用这个图作为backgroudimage,前图透明来重绘,不知道这个方法可可行,应该就是这个思路。
[/Quote]
你好,我发现我是直接将坐标轴画在了,groupbox中 直接画的线段组成的,像你说的画在picturebox 有什么本质性的区别吗?是不是要达到预期的效果就必须画在picturebox中?
shamohai5566 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 glest 的回复:]
可以调整算法,做成局部刷新,只刷新一个区域,GDI中称为“脏矩形”。

贴出代码,帮你调一下。
[/Quote]
我的代码
public static  void GrahpicsUpdate()
{
System.Drawing.Font font = new System.Drawing.Font("Arial", 8, FontStyle.Regular);
graphics.DrawLine(mypen, 0, 192, 700, 192);
//String[] n = { "0", ((double)MaxValue / 6).ToString(), ((double)MaxValue / 3).ToString(), ((double)MaxValue / 2).ToString(), ((double)MaxValue * 2 / 3).ToString(), ((double)MaxValue * 5 / 6).ToString(), ((double)MaxValue).ToString() };
String[] n = { "0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%" };
int xstart = 10;
for (int i = 0; i < 11; i++)
{
graphics.DrawString(n[i].ToString(), font, Brushes.DarkGray , xstart - 7, 192);//.Red
int Xmin = xstart;
for (int j = 0; j < 9; j++)
{
Xmin += 6;
if (j == 4) graphics.DrawLine(mypen, Xmin, 184, Xmin, 192);
else graphics.DrawLine(mypen, Xmin, 188, Xmin, 192);
}
graphics.DrawLine(mypen, xstart, 182, xstart, 192);
xstart = xstart + 60;
Thread.Sleep(1);
}
//graphics.DrawRectangle(mypen, 8, 192, 600, 10);
graphics1.DrawLine(mypen1, x1, 180, x1, 200);
}
private void groupBox2_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Font font = new System.Drawing.Font("Arial", 8, FontStyle.Regular);
graphics.DrawLine(mypen, 0, 192, 700, 192);
String[] n = { "0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%" };
int xstart = 10;
for (int i = 0; i < 11; i++)
{
graphics.DrawString(n[i], font, Brushes.DarkGray, xstart - 7, 192);//.Red
int Xmin = xstart;
for (int j = 0; j < 9; j++)
{
Xmin += 6;
if (j == 4) graphics.DrawLine(mypen, Xmin, 184, Xmin, 192);
else graphics.DrawLine(mypen, Xmin, 188, Xmin, 192);
}
graphics.DrawLine(mypen, xstart, 182, xstart, 192);
xstart = xstart + 60;
Thread.Sleep(1);
}
//graphics.DrawRectangle(mypen, 8, 192, 600, 10);
graphics1.DrawLine(mypen1, x1, 180, x1, 200);
}
private void textBox5_TextChanged(object sender, EventArgs e)
{

if (textBoxPresentVal.Text.Trim() != "")
{
double newdate = Convert.ToDouble(textBoxPresentVal.Text.Trim());
textBoxDiffer .Text = (1000*(newdate - Form_Main .CurrentStandOut ) / Form_Main.MaxValue).ToString();
int x = Convert.ToInt32(10 + newdate * 600 / Form_Main.MaxValue);
//if (graphics1 .TranslateClip ())
//graphics1.Clear(Color.White );.Transparent

if (Form_Main.XCount1 == 0)
{
Form_Main.graphics1.Clear(Color.WhiteSmoke);
Form_Main.graphics1.DrawLine(Form_Main.mypen1, x, 182, x, 202);
Form_Main.x1 = x;
Form_Main.XCount1++;
Form_Main.GrahpicsUpdate();

}
else
{
Form_Main.graphics1.Clear(Color.WhiteSmoke);
//Form_Main.graphics1.DrawLine(Form_Main.mypen1, x, 182, x, 202);
Form_Main.graphics1.TranslateClip(x - Form_Main.x1, 0);// .TranslateTransform
Form_Main.x1 = x;
Form_Main.XCount1++;
Form_Main.GrahpicsUpdate();
}
}
}

坐标上面的值是根据TEXTbox5中的具体值算出来的,请指点,在线等,谢谢
glest 2010-09-10
  • 打赏
  • 举报
回复
可以调整算法,做成局部刷新,只刷新一个区域,GDI中称为“脏矩形”。

贴出代码,帮你调一下。
yukunhu 2010-09-10
  • 打赏
  • 举报
回复
我试着解释下一楼的意思,比较你画好一个底图存为一个bmp或者别的格式,放在本地资源上,上面的坐标轴已经画好了,你下次把图清掉后,可一在把这个图load到picturebox上,再在上面画图,可能会轻松点,或者直接用这个图作为backgroudimage,前图透明来重绘,不知道这个方法可可行,应该就是这个思路。
shamohai5566 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wuyazhe 的回复:]
坐标轴你可以先绘制在一个底图上,每次贴图,或是每次clear后重绘。吧绘制坐标轴和网格的部分抽出单独方法。
[/Quote]clear不会连底图一起清空吗?
shamohai5566 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wuyazhe 的回复:]
坐标轴你可以先绘制在一个底图上,每次贴图,或是每次clear后重绘。吧绘制坐标轴和网格的部分抽出单独方法。
[/Quote]
首先感谢您的帮忙,我比较菜,能不能说的详细点,底图?用什么画呀?我第一次做画图的,很吃力。差了好多资料,但是没有什么进展
shamohai5566 2010-09-10
  • 打赏
  • 举报
回复
问题补充:我在上述GroupBox的Paint事件中写了重写事件,没胆界面刷新时,就会重画坐标轴要花100条竖线,感觉除此图之外的其他控件总是很卡,分批的显示出来不知道是什么原因,高手帮忙分析一下,谢谢
加载更多回复(1)

110,534

社区成员

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

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

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