winforms标签闪烁
我有一个问题,Label控件非常闪烁。
下面是一些重现问题的代码。
怎么解决这个?
更新:前一种情况的解决方案(表单直接包含标签)是使form.DoubleBuffered = true。 但这不是一般的解决方案。 例如,对于SplitContainer中的标签,我该怎么办? 这是我的真实情况。
更新的代码:
DoubleBufferedLabel.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace FlickerLabelTest { public class DoubleBufferedLabel : Label { public DoubleBufferedLabel() { DoubleBuffered = true; } } }
DoubleBufferedSplitContainer.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace FlickerLabelTest { public class DoubleBufferedSplitContainer : SplitContainer { public DoubleBufferedSplitContainer() { DoubleBuffered = true; } } }
Form1.cs中:
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; namespace FlickerLabelTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void timer1_Tick(object sender, EventArgs e) { label1.Text += "0"; } } }
Form1.Designer.cs:
namespace FlickerLabelTest { partial class Form1 { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.timer1 = new System.Windows.Forms.Timer(this.components); this.label1 = new FlickerLabelTest.DoubleBufferedLabel(); this.splitContainer1 = new DoubleBufferedSplitContainer(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); this.SuspendLayout(); // // timer1 // this.timer1.Enabled = true; this.timer1.Interval = 1; this.timer1.Tick += new System.EventHandler(this.timer1_Tick); // // label1 // this.label1.Dock = System.Windows.Forms.DockStyle.Fill; this.label1.Location = new System.Drawing.Point(0, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(186, 262); this.label1.TabIndex = 0; this.label1.Text = "label1"; // // splitContainer1 // this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; this.splitContainer1.Location = new System.Drawing.Point(0, 0); this.splitContainer1.Name = "splitContainer1"; // // splitContainer1.Panel2 // this.splitContainer1.Panel2.Controls.Add(this.label1); this.splitContainer1.Size = new System.Drawing.Size(284, 262); this.splitContainer1.SplitterDistance = 94; this.splitContainer1.TabIndex = 1; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(284, 262); this.Controls.Add(this.splitContainer1); this.DoubleBuffered = true; this.Name = "Form1"; this.Text = "Form1"; this.WindowState = System.Windows.Forms.FormWindowState.Maximized; this.splitContainer1.Panel2.ResumeLayout(false); this.splitContainer1.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Timer timer1; private DoubleBufferedLabel label1; private DoubleBufferedSplitContainer splitContainer1; } }
Program.cs中:
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace FlickerLabelTest { static class Program { /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } }
问题在于对接。 如果将Label.Dock
从“ Fill
更改为“ None
,请手动设置标签的大小以填充分割面板,然后将其锚定在所有面上,它不会闪烁。
如果要查看闪烁的原因,当Dock
仍设置为Fill
,覆盖DoubleBufferedLabel
类中的OnResize
,启动应用程序,并在运行时在OnResize
设置断点。 为Size
添加一个手表,您会看到它在设计时和运行时尺寸之间翻转。
我尝试在您的示例中使用常规的SplitContainer
和Label
,在表单DoubleBuffer
设置为False
,如果我在Label
上将Dock
设置为None
,则它不会闪烁。
将其粘贴到您的表单代码中以帮助Dock布局计算:
protected override void OnLoad(EventArgs e) { label1.Size = this.ClientSize; base.OnLoad(e); }
不是真正的答案,但为什么你想要每毫秒更新你的标签? 如果你的意思是1秒,你必须将你的间隔设置为1000。
你可以通过给表单时间重绘自己并使用更大的间隔来解决这个问题。
更新:结果是,将DoubleBuffered设置为true可以解决问题。 感谢csharptest.net指出这一点和DxCK纠正我。
我想你正在寻找这个: http : //msdn.microsoft.com/en-us/library/3t7htc9c.aspx
例:
class Form1 : Form { public Form1() { this.DoubleBuffered = true; } }
停止将定时器设置为1ms。 没有认真的,你在这里看到的是,标签试图跟上它的变化,但没有这样做,因为它们经常发生。 可能的解决方案是:
为什么不通过异步委托运行标签更新function? 或者使用System.Threading命名空间来获得不同的风格。
另外,正如我之前提到的那样,如果你将表单上的DoubleBuffer属性设置为true(虽然它不是银弹)会很有用。
在表单上激活双缓冲将解决问题。 但这实际上是一种昂贵的解决方案。 如果您只是将以下内容添加到表单中:
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
闪烁也将结束。
Windows操作系统的默认行为首先让所有窗口绘制背景,然后让它们进行实际绘制。 这是从过去开始,当时绘画字母实际上耗费了相当多的时间。 此标志告诉它立即折叠背景油漆和常规油漆(对于同一窗口)。
真正的双缓冲可以保留用于您实际自己绘画的情况(当您重写OnPaint时)。
上述就是C#学习教程:winforms标签闪烁分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1039302.html