(WinRT)How to get TextBox caret index?

2019-06-11 11:42发布


I got some problems with getting caret index of TextBox in Windows Store App(WP 8.1).
I need to insert specific symbols to the text when button is pressed. I tried this:

    text.Text = text.Text.Insert(text.SelectionStart, "~");



But this code inserts symbol to the beginning of text, not to the place where caret is.

UPDATE

I updated my code thanks to Ladi. But now I got another problem: I'm building HMTL editor app so my default TextBlock.Text is:

    <!DOCTYPE html>\r\n<html>\r\n<head>\r\n</head>\r\n<body>\r\n</body>\r\n</html>

So for example when user inserts symbol to line 3, symbol is inserted 2 symbols before caret; 3 syms before when caret is in line 4 and so on. Inserting works properly when symbol is inserted to the first line.

Here's my inserting code:

Index = HTMLBox.SelectionStart;
HTMLBox.Text = HTMLBox.Text.Insert(Index, (sender as AppBarButton).Label);
HTMLBox.Focus(Windows.UI.Xaml.FocusState.Keyboard);
HTMLBox.Select(Index+1,0);


So how to solve this?
I guess new line chars making trouble.

1条回答
三岁会撩人
2楼-- · 2019-06-11 12:26

For your first issue I assume you changed the TextBox.Text before accessing SelectionStart. When you set the text.Text, text.SelectionStart is reset to 0.

Regarding your second issue related to new lines.

You could say that what you observe is by design. SelectionStart will count one "\r\n" as one character for reasons explained here (see Remarks section). On the other hand, method string.Insert does not care about that aspect and counts "\r\n" as two characters.

You need to change slightly your code. You cannot use the value of SelectionStart as the insert position. You need to calculate the insert position accounting for this behavior of SelectionStart.

Here is a verbose code sample with a potential solution.

// normalizedText will allow you to separate the text before 
// the caret even without knowing how many new line characters you have.
string normalizedText = text.Text.Replace("\r\n", "\n");
string textBeforeCaret = normalizedText.Substring(0, text.SelectionStart);

// Now that you have the text before the caret you can count the new lines.
// that need to be accounted for.
int newLineCount = textBeforeCaret.Count(c => c == '\n');

// Knowing the new lines you can calculate the insert position.
int insertPosition = text.SelectionStart + newLineCount;

text.Text = text.Text.Insert(insertPosition, "~"); 

Also you should make sure that SelectionStart does not exhibit similar behavior with other combinations beside "\r\n". If it does you will need to update the code above.

查看更多
登录 后发表回答