どうにかして、Googleや私の言葉の問題が私に解決策をもたらさない場所に自分自身を戻すことができます。カーソルを点滅させるためにカスタムコントロールにタイマーを追加する
このように、System.Windows.Forms.Control
から派生したTextBox
をゼロから作成しています。私はこれまでにText
変数を描画することができましたし、編集機能も追加しました(普通のTextBox
のように)。
恐ろしい時間のかかる練習のアイデアは、私が開発したソフトウェアで使用するために最大限のテーマ機能を持つ独自のライブラリを作成することです。
したがって、私の問題:TextBox
に点滅カーソルを描画します。
私は、CursorPosition
がどこにあるかに応じて左から右に移動する静的線を描くことができます。コントロール(したがってif(blinker)
)からSystem.Timers.Timer
までのタイマーを追加しましたが、System.Windows.Forms.Timer
も試しましたが、コントロールがフォームに追加されても描画イベントを発生させないときに私のプロパティを設定することを許可しないため、 。 Tick
イベントにInvalidate(_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
タイマー自体は、コントロールが最初にフォーカスを取得したときにのみ開始され、フォーカスが失われると停止します。クラスにTimerを追加するだけで、私はVS Desingerを使用することができません。自分のデザイナーのスクリーンショットをオリジナルの投稿に追加して追加します。 – Hurly
タイマーは静的なものにする必要があります。制御。 OnEnter/OnLeave()のオーバーロードで、それを作成して(nullの場合)、Tickイベントの登録を解除/登録するのがベストです。また、設計時に決して使用されないようにし、何かを "混乱させる"ことはできません。 –