[英]How to use the Control.Update method in a custom control
由於代碼簡短且易於理解,因此我將首先發布我的代碼,然后再問我一個問題。
public class BatteryLabel : Control
{
private Color _captionColor = SystemColors.Control;
private Color _textColor = SystemColors.Info;
private Color _failColor = Color.Red;
private Color _passColor = Color.Green;
private string _caption;
string text2;
string text3;
bool battery1Fail = false;
bool battery2Fail = false;
bool battery3Fail = false;
public BatteryLabel()
{
}
public Color BackgroundTextColor
{
get{ return _textColor;}
set{_textColor = value; Invalidate();}
}
public string Caption
{
get
{
return _caption;
}
set
{
_caption = value;
Invalidate();
}
}
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
Invalidate();
}
}
public string Text2
{
get { return text2; }
set { text2 = value; Invalidate(); }
}
public string Text3
{
get { return text3; }
set { text3 = value; Invalidate(); }
}
public bool Battery1Fail
{
get { return battery1Fail; }
set { battery1Fail = value; Invalidate(); }
}
public bool Battery2Fail
{
get { return battery2Fail; }
set { battery2Fail = value; Invalidate(); }
}
public bool Battery3Fail
{
get { return battery3Fail; }
set { battery3Fail = value; Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawRectangle(Pens.Black, 0,0, Width-1, Height-1);
var x1 = 50;
var x2 = 98;
var x3 = 146;
var color1 = battery1Fail?_failColor:BackgroundTextColor;
var color2 = battery2Fail?_failColor:BackgroundTextColor;
var color3 = battery3Fail?_failColor:BackgroundTextColor;
e.Graphics.FillRectangle(new SolidBrush(color1),x1+1, 1, 47, Height-2);
e.Graphics.FillRectangle(new SolidBrush(color2),x2+1, 1, 47, Height-2);
e.Graphics.FillRectangle(new SolidBrush(color3),x3+1, 1, 47, Height-2);
e.Graphics.DrawLine(Pens.Black, x1,0, x1, Height-1);
e.Graphics.DrawLine(Pens.Black, x2,0, x2, Height-1);
e.Graphics.DrawLine(Pens.Black, x3,0, x3, Height-1);
var BoldFont = new Font(this.Font, FontStyle.Bold);
e.Graphics.DrawString(Caption, BoldFont, new SolidBrush(ForeColor), 0,0);
e.Graphics.DrawString(Text, this.Font, new SolidBrush(ForeColor), x1,0);
e.Graphics.DrawString(Text2, this.Font, new SolidBrush(ForeColor), x2,0);
e.Graphics.DrawString(Text3, this.Font, new SolidBrush(ForeColor), x3,0);
}
}
控件的大小應為195,14,以防萬一您決定嘗試使用它。 我有一個面板中有8個,它們是在1.6Ghz原子處理器上運行的200,200。 它用於在計算機上顯示多達3個電池的值。 標簽每500毫秒刷新一次。 您可能已經聚集了一點點的閃爍,但這是可以忍受的。 如果可能的話,我想減少的更多。 因此,我開始研究使用Update,並移動一些代碼,例如背景位,我認為我應該將其移至OnPaintBackground(),但在組成Update方法的測試框架中,它並沒有做任何更改,並且當我使用Invalidate方法時,它同時運行OnPaintBackground和OnPaint。 這是我在這種情況下嘗試過的。
public class InformationLabel : Control
{
Random r = new Random();
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
Color randomCOlor = Color.FromArgb(r.Next());
e.Graphics.FillRectangle(new SolidBrush(randomCOlor),0,0, Width-1, Height-1);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Color randomCOlor = Color.FromArgb(r.Next());
e.Graphics.FillPie(new SolidBrush(randomCOlor),15,15,15,15, 0.0f, 120.0f);
}
}
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
void Button1Click(object sender, EventArgs e)
{
informationLabel1.Update();
}
void Button2Click(object sender, EventArgs e)
{
informationLabel1.Invalidate();
}
}
我使一個用戶控件大約300,300,因此我可以確定自己所看到的。 我忘了提到在500ms計時器的電池控制中,我只是續訂text,text2和text3。 我在想,如果該文本的值超出規范,我將設置電池故障標志,然后使它無效..但我不確定。 那么我應該如何只更新文本呢???
您可以通過在構造函數中添加以下代碼來消除閃爍:
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.AllPaintingInWmPaint, true);
現在,在油漆處理程序中同時繪制背景和其他所有內容。
可以通過僅對需要重繪的區域傳遞一個“矩形”到“無效”來進行優化。 然后在OnPaint覆蓋中,使用e.ClipRectangle確定要繪制的內容。 對於這樣的簡單繪圖,這可能不是必需的。
我相信您在尋找錯誤的地方以消除閃爍。 我可以使用BatteryLabel
基本上只用一行就可以無閃爍地更新文本。 更改您的構造函數,如下所示:
public BatteryLabel()
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer,true);
}
這告訴控件對其圖形進行雙緩沖,從而消除了閃爍。
要以100毫秒的刷新間隔進行測試:
Timer t;
public Form1()
{
InitializeComponent();
t = new Timer();
t.Interval = 100;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
string ticks = DateTime.Now.Ticks.ToString();
string ticks1 = ticks.Substring(ticks.Length-4),
ticks2 = ticks.Substring(ticks.Length - 5,4),
ticks3 = ticks.Substring(ticks.Length - 6,4);
batteryLabel1.Text = ticks1;
batteryLabel1.Text2 = ticks2;
batteryLabel1.Text3 = ticks3;
batteryLabel1.Battery1Fail = ticks1.StartsWith("1");
batteryLabel1.Battery2Fail = ticks2.StartsWith("1");
batteryLabel1.Battery3Fail = ticks3.StartsWith("1");
}
這是否有幫助,或者我誤解了您?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.