Elad
Elad

Reputation: 20179

How to know on which letter the user clicked in a WPF TextBlock

I have a TextBlock that presents a text. When the user clicks on the text, it is dynamically replaced with a TextBox (which is binded to the same data), effectively switching into "edit mode". This also significantly improves the performance.

The only caveat is that I am not able to know which part of the text the user clicked on. Therefore, the cursor always appears at the first position on the TextBox. Ideally, the cursor should appear in the same text position that the user clicked on.

Upvotes: 2

Views: 1502

Answers (3)

JWWalthers
JWWalthers

Reputation: 45

A little late, but I was wrestling with the same problem and this is the solution I came up with, crude though it may be, it seems to work just fine:

<Window x:Class="MyWindow.MainWindow"
...
...
<TextBlock MouseLeftButtonUp="TextBlock_OnMouseLeftButtonUp">Here is some Text</TextBlock>
<TextBox Name="TextBox1" Width="150"></TextBox>

Then, in the code behind:

private void TextBlock_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    TextBlock tb = sender as TextBlock;
    TextPointer tp = tb.GetPositionFromPoint(e.GetPosition(tb), false);

    int index = tp.GetLineStartPosition(0).GetOffsetToPosition(tp) - 1;

    TextBox1.Text = tb.Text;
    TextBox1.Focus();
    TextBox1.CaretIndex = index;

}

Upvotes: 2

Elad
Elad

Reputation: 20179

Apperantly, The solution is quite simple and straightforward. However, It still uses TextBox and not TextBlock. The following method receives MouseButtonEventArgs from a mouse click event and the TextBox that triggered the event and return the text index on which the user clicked.

private int GetMouseClickPosition(MouseButtonEventArgs mouseButtonEventArgs, 
                                  TextBox textBox1)
    {
        Point mouseDownPoint = mouseButtonEventArgs.GetPosition(textBox1);
        return textBox1.GetCharacterIndexFromPoint(mouseDownPoint, true);
    }

Upvotes: 2

Amsakanna
Amsakanna

Reputation: 12934

Try this:

  1. Create a TextBox
  2. Create a Style named LockedTextBoxStyle
    • BorderThickness: 0
    • IsReadOnly: True
    • IsReadOnlyCaretVisible: True
    • Cursor: Arrow
  3. Create a trigger for IsKeyboardFocused When true set the style to LockedTextBoxStyle

Since IsReadOnlyCaretVisible is set to true, I hope that would preserve the caret position. Haven't tested yet.

Upvotes: 1

Related Questions