在C#中将Graphics.DrawString用于计时器时,如何减少闪烁?

用户名

以下是将文本绘制到进度条上的C#代码。它用于将文本添加到进度条,以显示剩余时间的倒计时。我使用Graphics类来绘制字符串而不是Windows Form标签,因为当放置在进度条上时,标签背景不能设置为透明。

但是,使用此代码,文本在每次更新时都会闪烁(此方法在每秒滴答一次的计时器中被调用),因此它几乎一直闪烁并且无法使用。

/// <summary>
    /// Adds time remaining text into a System.Windows.Forms.ProgressBar
    /// </summary>
    /// <param name="target">The target progress bar to add text into</param>
    /// <param name="remainingTimeText">The text to add into the progress bar.</param>
    private void set_progress_bar_text( System.Windows.Forms.ProgressBar target, string remainingTimeText )
    {
        // Make sure we do not have a null progress bar.
        if( target == null )
        {
            throw new ArgumentException( "Null Target" );
        }

        // Use the progress bar label font and size.
        Font textFont = new Font( labelProgress.Font.Name, labelProgress.Font.Size );

        // gr will be the graphics object we use to draw on the progress bar.
        using( Graphics gr = target.CreateGraphics() )
        {
            gr.DrawString( remainingTimeText,
                textFont,
                new SolidBrush( Color.Black ), // The brush we will use to draw the string, using a black colour.

                // The position on the progress bar to put the text.
                new PointF(
                // X location of text, to be placed at the centre of the progress bar.
                    progressBar.Width / 2 - ( gr.MeasureString( remainingTimeText,
                    textFont ).Width / 2.0F ),
                // Y Location
                progressBar.Height / 2 - ( gr.MeasureString( remainingTimeText,
                    textFont ).Height / 2.0F ) ) );
        }
    }

我已尝试DoubleBuffered = true按照堆栈溢出相关问题的建议在此方法内进行设置,但它不能防止闪烁。我无法减少文本更新的次数,因为文本是一个倒计时时钟,必须每秒更新一次。有没有办法通过双缓冲来防止闪烁,或者还有其他潜在的解决方案吗?

拉尔夫

ProgressBar似乎是试图隐藏绘画的那些控件之一。因此,我们需要自己动手。只需与此交换您的ProgressBar。

如注释中所述,添加了CreateParams覆盖以减少闪烁。

public class MyLovelyProgressBar : ProgressBar
{
    public MyLovelyProgressBar()
    {
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    }

    private string foregroundText;
    public string ForegroundText 
    {
        get { return foregroundText;  }
        set 
        {
            if (foregroundText != value)
            {
                Invalidate();
                foregroundText = value;
            }
        } 
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams result = base.CreateParams;
            result.ExStyle |= 0x02000000; // WS_EX_COMPOSITED 
            return result;
        }
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        switch (m.Msg)
        {
            case 15: //WmPaint
                using (var graphics = Graphics.FromHwnd(Handle))
                    PaintForeGroundText(graphics);
                break;
        }
    }

    private void PaintForeGroundText(Graphics graphics)
    {
        if (!string.IsNullOrEmpty(ForegroundText))
        {
            var size = graphics.MeasureString(ForegroundText, this.Font);
            var point = new PointF(Width / 2.0F - size.Width / 2.0F, Height / 2.0F - size.Height / 2.0F);
            graphics.DrawString(ForegroundText, this.Font, new SolidBrush(Color.Black), point);
        }
    }
}

然后只需在您的Timer事件中更改该ProgressBar的ForegroundText。

myLovelyProgressBar1.ForegroundText = "A constantly changing lovely text";

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在C#中将Graphics.DrawString用于计时器时,如何减少闪烁?

来自分类Dev

带有计时器的 C# 动画使背景闪烁

来自分类Dev

C#如何暂停计时器?

来自分类Dev

Linux,C,如何取消计时器?

来自分类Dev

Linux,C,如何取消计时器?

来自分类Dev

如何停止在C#类中运行的计时器

来自分类Dev

用于完成块的Objective-C计时器

来自分类Dev

如何在Android中将计时器用作倒数计时器

来自分类Dev

C#,WinForms,等待计时器

来自分类Dev

计时器不停止C#

来自分类Dev

C#计时器和内存

来自分类Dev

C#中的延迟计时器

来自分类Dev

c#倒数计时器暂停

来自分类Dev

我如何在 C# 中编写计时器倒计时?

来自分类Dev

您如何在Objective-C中将计时器显示为屏幕上的标签?

来自分类Dev

如何在C#中创建计时器计数器

来自分类Dev

如何在C ++程序中添加计时器

来自分类Dev

如何立即启动c中的计时器

来自分类Dev

如何在 C 中运行计时器

来自分类Dev

在AS3中将计时器事件用于动画

来自分类Dev

当计时器从 C# 控制台应用程序中的其他类停止时如何返回主程序

来自分类Dev

如何在C#中设置计时器以在特定时间执行

来自分类Dev

如何使用反应性扩展(C#)控制计时器而没有任何副作用?

来自分类Dev

如何使用C#在通用Windows应用程序中包含计时器

来自分类Dev

如何使C#计时器触发主线程中的事件?

来自分类Dev

如何在Unity 3D中使用C#创建计时器

来自分类Dev

如何在C#的datagridview列中动态显示数字计时器(StopWatch)?

来自分类Dev

如何在C#中设置计时器以在特定时间执行

来自分类Dev

C#如何通过单个计时器通知其他类?

Related 相关文章

热门标签

归档