Hi, I used the following algorithm to create a custom cursor for TextBox:
<Window.Resources>
<Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
<Setter Property="CaretBrush" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border Background="{TemplateBinding Background}"
x:Name="TextBox" BorderBrush="DarkGray"
BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="9">
<ScrollViewer x:Name="PART_ContentHost"/>
</Border>
<Canvas ClipToBounds="True">
<Border x:Name="TextBoxCaret" Width="1.5" Margin="{Binding ElementName=TextBox,Path=Value}" Padding="4,4,0,0" Visibility="Collapsed" Background="Transparent">
<Border.Triggers>
<EventTrigger RoutedEvent="Border.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Background.Color" FillBehavior="HoldEnd">
<ColorAnimationUsingKeyFrames.KeyFrames>
<EasingColorKeyFrame KeyTime="0:0:1.0" Value="Black"/>
<EasingColorKeyFrame KeyTime="0:0:2.0" Value="Transparent" />
</ColorAnimationUsingKeyFrames.KeyFrames>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border>
</Canvas>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" TargetName="TextBox"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="Width" Value="Auto">
<Setter Property="MinWidth" Value="100"/>
</Trigger>
<Trigger Property="Height" Value="Auto">
<Setter Property="MinHeight" Value="20"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TextBox x:Name="BookName_TextBox" GotFocus="BookName_TextBox_GotFocus" LostFocus="BookName_TextBox_LostFocus" Padding="4,4,0,0" HorizontalAlignment="Left" Height="30" TextWrapping="Wrap" VerticalAlignment="Top" Width="267" Margin="21,64,0,0"/>
</Grid>
Code behind:
public void MoveCaret(TextBox TextBoxName)
{
TextBoxName.LayoutUpdated += (sender, e) =>
{
switch (TextBoxName.GetRectFromCharacterIndex(TextBoxName.CaretIndex).IsEmpty)
{
case true:
return;
default:
var Rect = TextBoxName.GetRectFromCharacterIndex(TextBoxName.CaretIndex);
Border Caret = TextBoxName.Template.FindName("TextBoxCaret", TextBoxName) as Border;
Canvas.SetLeft(Caret, Rect.Left);
Canvas.SetTop(Caret, Rect.Top);
Caret.Height = Rect.Height;
break;
}
};
}
private void BookName_TextBox_GotFocus(object sender, RoutedEventArgs e)
{
MoveCaret(BookName_TextBox);
var Border = BookName_TextBox.Template.FindName("TextBoxCaret", BookName_TextBox) as Border;
Border.Visibility = Visibility.Visible;
}
private void BookName_TextBox_LostFocus(object sender, RoutedEventArgs e)
{
var Border = BookName_TextBox.Template.FindName("TextBoxCaret", BookName_TextBox) as Border;
Border.Visibility = Visibility.Collapsed;
}
The result:
Click to see
As you can see in the image below, if I use the algorithm mentioned above, the cursor is always at the end of the text; but, if I don't use that algorithm, the cursor will be at the proper location.
Custom (using the algorithm):
Click to see
Standard (without using the algorithm):
Click to see
How can the above algorithm's problem be solved?
If someone answers correctly, I will give them 5 stars.
Thanks.
What I have tried:
I tried using the
FlowDirection
property, but nothing happened.