不知何故,我設法讓自己重新找到一個地方,Google或我的問題的措辭都不能解決問題。將定時器添加到自定義控件以創建閃爍光標
因此,要這樣說,我要創建一個TextBox
從零開始,從System.Windows.Forms.Control
派生。到目前爲止,我已經能夠繪製Text
變量,並且還添加了編輯功能(正常的TextBox
通常會這樣做)。
可怕的耗時練習的想法是創建我自己的自定義控件庫,它具有與我開發的軟件一起使用的最大主題功能。
所以,我的問題:在TextBox
中繪製閃爍的光標。
我可以繪製一條靜態線,該線從左至右移動,具體取決於CursorPosition
拍攝的位置。向控件添加了一個計時器(因此if(blinker)
)到System.Timers.Timer
並且還嘗試了System.Windows.Forms.Timer
,但是通過不允許我在將控件添加到表單時設置我的任何屬性並且仍然無法啓動繪圖事件。我確實在Tick
事件中放置了Invalidate(_Cursor)
,以確保只有Cursor位置被重新繪製,甚至在沒有參數的情況下嘗試,仍然無濟於事。
protected override void OnPaint(PaintEventArgs e)
{
...
if (Focused)
{
if (blinker)
e.Graphics.FillRectangle(new SolidBrush(_CursorColor), _Cursor);
foreach (Rectangle border in Borders)
{
if(_DrawBorders[Borders.IndexOf(border)])
e.Graphics.FillRectangle(new SolidBrush(BorderColor), border);
}
}
...
}
我還設置
DoubleBuffered = true;
SetStyle(ControlStyles.UserPaint | ControlStyles.Selectable | ControlStyles.ResizeRedraw |
ControlStyles.OptimizedDoubleBuffer | ControlStyles.StandardClick | ControlStyles.AllPaintingInWmPaint, true);
與一個可怕的閃爍和輸入的問題我有幫助。
EDIT **(REMOVED AS IT IS FIXED USING COMMENT BY Hans Passant's SUGGESTION)**
好了,現在該定時器的工作,對這個問題我上面所述。繪製光標。
private void _CursorBlinkTime_Tick(object sender, EventArgs e)
{
blinker = !blinker;
Console.WriteLine("Blink!");
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
Height = TextRenderer.MeasureText("A", Font).Height + (2 * BorderWidth) + (2 * TextPadding);
CursorPosition = (BorderWidth + TextPadding) + (_SelectedStart * (TextRenderer.MeasureText("_", Font).Width));
_InputBounds = new Rectangle(BorderWidth + TextPadding, BorderWidth + TextPadding, Width - (2 * BorderWidth) - (2 * TextPadding), Height - (2 * BorderWidth));
base.OnPaint(e);
e.Graphics.Clear(BackColor);
e.Graphics.DrawString(Text, Font, new SolidBrush(TextColor), _InputBounds.Location);
foreach (Rectangle border in Borders)
{
if (_DrawBorders[Borders.IndexOf(border)])
e.Graphics.FillRectangle(new SolidBrush(InactiveBorderColor), border);
}
if (Focused)
{
// This is where the Cursor is drawn, right before the borders.
// I've tried to move it to after the border is drawn but same result, nothing is drawn.
// I've ran through the entire OnPaint using Step-by-Step and while it does
// fire the draw event, nothing is drawn.
// BackColor = FromArgb(40,40,40), _CursorColor = Color.Red
// _Cursor is a Rectangle that reads at this moment:
// Rectangle(5,0,2,21) Which given all other variables should show result?
if (blinker)
e.Graphics.FillRectangle(new SolidBrush(_CursorColor), _Cursor);
foreach (Rectangle border in Borders)
{
if(_DrawBorders[Borders.IndexOf(border)])
e.Graphics.FillRectangle(new SolidBrush(BorderColor), border);
}
}
else if (!Focused)
{
if(string.IsNullOrWhiteSpace(Text))
e.Graphics.DrawString(WaterMarkText, Font, new SolidBrush(WaterMarkColor), _InputBounds.Location);
}
}
所以你的問題是隻有在VS設計師?您可以添加一個條件來啓動計時器,如下所示:'if(!DesignMode)yourtimer.Start();' – TaW
只有當控件第一次獲得焦點時才啓動計時器,然後在焦點丟失時停止。只是添加計時器到課堂的事實阻止我使用VS Desinger,我會添加我的設計器的截圖到原始文章並添加。 – Hurly
計時器應該是* static *,以便它可以閃爍任何控制。最好創建它(如果爲null),並在OnEnter/OnLeave()的重載中取消/訂閱其Tick事件。同時確保它不會在設計時使用,也不會「搞砸」任何東西。 –