利用GDI+逐行显示文字

cykevin 2010-05-25 04:26:14
有一段文字,按照需求需要一行一行的显示出来,每行间隔1s

我目前采取的思路是这样的:
自定义一个控件,重写onPaint方法,在onPaint中将e.Graphics赋给一个全局变量,然后启动一个timer,在timer的事件里面去用这个全局的Graphics画一行,timer每执行一次就画一行。

此种方法在timer中引用全局的Graphics时报错 argumentException。很困惑。

我感觉应该是这种思路存在问题,但是为什么会报错又说不上来。难道Graphics不能作为类中的全局变量么?

如果不用Timer的话,直接用GDI+在onPaint中一次性画出来是没有问题的。

还请高人解惑。
...全文
188 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
cykevin 2010-05-27
  • 打赏
  • 举报
回复
我不是做LED屏的。
各位虽然说出了可行的方法,可是并没有回答我问的问题。算了结贴。
一克代码 2010-05-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gomoku 的回复:]
C# code
public partial class Form1 : Form
{
Timer timer = new Timer();
string[] lines = { "hellow world", "nihao", "line3", "line4", "line5", "end" };
int currentLine = 0;

publ……
[/Quote]

我试了试可以啊!


对了,楼主你是不是在做LED屏的啊?
zzx509 2010-05-25
  • 打赏
  • 举报
回复
测量文字的长度,有两种方法。
TextRenderer.MeasureText("abc", Font);

Graphics g = this.CreateGraphics();
g.MeasureString("abc", Font);
但以上也只是大致的大小,你可以测量总长后除以宽度得出大致行数。
cykevin 2010-05-25
  • 打赏
  • 举报
回复
zzx509:
不知道richtextbox或是一般的文本编辑控件是如何来确定显示不下时换行的,能否提供下思路?
afeng124 2010-05-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gomoku 的回复:]
C# code
public partial class Form1 : Form
{
Timer timer = new Timer();
string[] lines = { "hellow world", "nihao", "line3", "line4", "line5", "end" };
int currentLine = 0;

publ……
[/Quote]
牛。
zzx509 2010-05-25
  • 打赏
  • 举报
回复
这个功能可以不用GDI+,有Timer就行了。

string[] lines;//所有文字,每行都有回车
int nextLine; //下一行
private void button2_Click(object sender, EventArgs e)
{
richTextBox1.Text =Resources.String1;
lines=richTextBox1.Lines;
richTextBox1.Text = "";
timer1.Interval = 1000;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}

void timer1_Tick(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder(richTextBox1.Text);
if (richTextBox1.Text != "")
{
sb.Append("\r\n");
}
sb.Append(lines[nextLine]); //添加下一行文字
richTextBox1.Text = sb.ToString();
richTextBox1.Select();
richTextBox1.SelectionStart = richTextBox1.Text.Length;
nextLine++;
if (nextLine >= lines.Length)
{
timer1.Enabled = false;
}
}

上面是一个大致的实现,可以在这个思路上进一步改进效果。
liss_2009 2010-05-25
  • 打赏
  • 举报
回复
路过,帮顶!
cykevin 2010-05-25
  • 打赏
  • 举报
回复
必须这样弄成string数组么,控件大小会变,不好确定每行该显示多少个字啊。
mngzilin 2010-05-25
  • 打赏
  • 举报
回复
假设你的图显示在picturebox1上面:

你可以在onPaint中将一张全局的bitmap画上去,为防止闪屏,这里只负责drawimg。

在timer中对bitmap进行绘制,所用的Graphics来自Graphics.fromimage(bitmap) 然后调用picturnbox1.refresh()即可。
gomoku 2010-05-25
  • 打赏
  • 举报
回复
string[] lines = "hellow world\nnihao\nline3\nline4\nline5\nend".Split('\n');
cykevin 2010-05-25
  • 打赏
  • 举报
回复
gomoku
如果是一整段文字该如何来做?
deknight 2010-05-25
  • 打赏
  • 举报
回复
mark
gomoku 2010-05-25
  • 打赏
  • 举报
回复
public partial class Form1 : Form
{
Timer timer = new Timer();
string[] lines = { "hellow world", "nihao", "line3", "line4", "line5", "end" };
int currentLine = 0;

public Form1()
{
InitializeComponent();
timer.Interval = 300;
timer.Tick += delegate { currentLine++; this.Invalidate(); };
timer.Start();
}

protected override void OnPaint(PaintEventArgs e)
{
for (int i = 0; i < currentLine % lines.Length; i++)
{
e.Graphics.DrawString(lines[i], this.Font, Brushes.Black, 10, 20 * i);
}
}
}

110,535

社区成员

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

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

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