Non-Blinking Caret in WPF Textbox

A recent question I came across recently was “How could one stop the caret in a WPF Textbox from blinking ?“.

My first instinct drove me in the direction of HideCaret method, but quickly realized WPF applications doesn’t allow you to get the Handle for individual controls. It only provides handles for Windows. This was quite unlike WinForm applications and ruled out usage of HideCaret API as it requires Handle for the control to disable the Caret.

The next solution I came up with ( and am still sticking on to it until i get a better one) was to emulate the behavior. What if it was possible to disable the original caret and mock the behavior using something else. The first part of the challenge was pretty easy, you could set the CaretBursh property to a Transparent color and the original Caret is hidden.

<TextBox x:Name="txtName" CaretBrush="Transparent" />

But the more important question was how to mock the caret. The solution lies in using a Canvas and Border overlaying the Textbox to emulate the caret. Let’s update our XAML first.

<Grid>
<TextBox x:Name="txtName" CaretBrush="Transparent" />
<Canvas>
<Border x:Name="Caret" Visibility="Collapsed" Canvas.Left="0" Canvas.Top="0" Width="1" Height="15" Background="Black"/>
</Canvas>
</Grid>

The final act of the trick involves writing a bit of code-behind logic.

txtName.SelectionChanged += (sender, e) => MoveCustomCaret();
txtName.LostFocus += (sender, e) => Caret.Visibility = Visibility.Collapsed;
txtName.GotFocus += (sender, e) => Caret.Visibility = Visibility.Visible;

Where the MoveCustomCaret is defined as

private void MoveCustomCaret()
{
var caretLocation = txtName.GetRectFromCharacterIndex(txtName.CaretIndex).Location;

if (!double.IsInfinity(caretLocation.X))
{
Canvas.SetLeft(Caret, caretLocation.X);
}

if (!double.IsInfinity(caretLocation.Y))
{
Canvas.SetTop(Caret, caretLocation.Y);
}
}

And now you have your non-blinking caret in textbox ready. Here is a screenshot of the control.

sample1

If you have a better solution, please let me know. That would be interesting to learn.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s