我会先说我已经尝试了很多方法来实现我的目标,我现在停留在“最佳”解决方案上,但它离我认为的“伟大”还很远。 .so 我希望在这里得到建议。这是在 C# 中使用 Visual Studio 2010。
我的程序播放带有可能包含歌词的元数据的音频文件。当我有歌词时,用户可以选择让歌词一次显示一个短语,或者随着音频滚动。这发生在单行标签上。这不是卡拉 OK 风格,你有整个短语,它被涂上颜色或其他东西,从字面上看,歌词随着音乐从左到右滚动。
我尝试过启用和禁用 DoubleBuffering。启用它后,它会更好,但仍然不完美。
1) 在运行时为标签创建一个 Graphics 对象,然后计时器将使用其 Graphics 对象直接绘制到 Label 上。我尝试了清除图形,而不是只绘制一个图形大小的填充矩形以避免清除闪烁。在其中任何一个之后,绘制文本字符串。我在这里尝试了 25 毫秒、50 毫秒和 100 毫秒,结果大致相同。
2) 在运行时为标签创建一个 Graphics 对象,然后计时器将创建一个标签大小的位图,从该位图创建一个图形对象,绘制填充的矩形并在图形对象中绘制字符串,然后将其复制到 Label 的图形对象,我还尝试将位图复制到 Label.Image 字段。
3) 没有创建专门的图形对象。相反,让计时器使标签无效。然后在 Label 的 Paint 事件上,使用 e 参数的 Graphics 对象直接绘制填充的矩形并绘制文本字符串。
在所有情况下,结果都是正确滚动的文本,滚动时抖动且难以阅读,但在播放暂停时看起来很完美。绘制的时间和内容是准确的。 #3 是我尝试过的许多变体中“最好的”,但正如我所说,阅读文本仍然不容易。考虑到计时器值在 40FPS 和 10FPS 之间变化,并且结果在易读性上差别不大,我假设这归结为我的绘图方式效率低下。
是我犯了一些明显的错误还是根本缺乏基础导致了这种行为?我希望就如何改进这一点提供一些意见。谢谢。
最佳答案
当您尝试以这种方式在控件上绘制时,控件将“有帮助地”为您绘制它的背景。不幸的是,这会导致闪烁。
我过去所做的是创建一个新类,它继承您实际想要绘制的控件。此类应使用空子覆盖 OnPaintBackground
。然后在您的表单上使用这个子类而不是股票类。
我只对图片框执行过此操作,因此使用其他类型控件的结果可能会有所不同。
您也可能运气不错,像这样设置控件样式(AllPaintingInWmPaint
在这种情况下是最重要的样式。):
this.SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,
true);
关于visual-studio-2010 - C#VS2010 : how to draw scrolling text using drawstring without flicker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28565326/