简体   繁体   中英

How to prevent flickering in WinForms when quickly updating a value?

I have a simple Winforms GUI which has a TrackBar in a GroupBox its title I'm using to display the value of the contained TrackBar:

private void trackBar1_Scroll(object sender, EventArgs e)
{
    UpdateTrackBarPositionText();
}

private void Form1_Load(object sender, EventArgs e)
{
    UpdateTrackBarPositionText();
}

private void UpdateTrackBarPositionText()
{
    groupBox1.Text = ORIGINAL_TRACKBAR_TEXT + qualitySelector.Value.ToString();
}

The problem is that when scrubbing over the bar, both it and the label of the group are flickering, especially when scrubbing quickly. Also CPU usage is fairly high for such a simple action. How can I improve this implementation? I want to update the value in real time, not just after letting go, so that the users sees the value while selecting it. DoubleBuffered = true; does nothing.

EDIT: I used reflection at instantiation to set the GroupBox and the bar to double buffered. That helped with the Box, but the slider still flickers :(

This is a classical use case for a timer. Make it update the label at, say, 10 times per second. Any more than that is really an overkill because nobody can read it that fast anyway.

You can have the timer permanently enabled, or (as an optimization) you can enable it at trackBar1_Scroll and disable it in the timer itself, if the value hasn't changed for the past few ticks. In fact, if the value hasn't changed since the last update, don't update the label either (might save some extra flickering).

Do you have Double Buffering set. If not start there and then other methods as needed.

This does not address this question, but it creates a workaround with a custom control that does the same thing.

PIC

public partial class SliderControl : Control
{
    public event EventHandler ValueChanged;
    public int MinValue { get; set; } 
    public int MaxValue { get; set; }
    public int Value { get; set; }
    public SliderControl()
    {
        InitializeComponent();
        SetStyle(ControlStyles.AllPaintingInWmPaint|ControlStyles.OptimizedDoubleBuffer, true);
        this.MinValue=0;
        this.MaxValue=100;
        this.Value=50;
        this.Text="Value";
    }

    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);

        SetBoundsCore(Left, Top, Width, 32, BoundsSpecified.Height);
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
        pe.Graphics.DrawRectangle(Pens.Black, 0, 0, Width-1, Height-16);
        using (var gp = new GraphicsPath())
        {
            var rect = new Rectangle(0, 0, Value*(Width-1)/MaxValue-1, Height-16);
            gp.AddRectangle(rect);
            using (var br = new LinearGradientBrush(rect, Color.SteelBlue, Color.LightBlue, LinearGradientMode.Horizontal))
            {
                pe.Graphics.FillPath(br, gp);
                pe.Graphics.DrawPath(Pens.DarkBlue, gp);
            }
        }
        var text = $"{this.Text} = {this.Value}";
        var sz = pe.Graphics.MeasureString(text, SystemFonts.SmallCaptionFont);
        pe.Graphics.DrawString(text, SystemFonts.SmallCaptionFont, Brushes.Black, Width/2-sz.Width/2, Height-16);
    }

    private void SetClickValue(Point click_point)
    {
        int x = (click_point.X+1)*MaxValue/Width;
        this.Value=x;
        this.Refresh();
        this.ValueChanged?.Invoke(this, new EventArgs());
    }

    protected override void OnMouseClick(MouseEventArgs e)
    {
        base.OnMouseClick(e);

        if (e.Button==MouseButtons.Left)
        {
            SetClickValue(e.Location);
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);

        if (e.Button==MouseButtons.Left)
        {
            SetClickValue(e.Location);
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM