我有一个带有wordwrap的多行文本框,而我希望它的光标位于下一行的开头,当它到达当前行的末尾时。
e.g。 - 如果可以在行中输入8个字符(等宽字体),我输入:
12345678
我希望光标位于'1'字符下(而不是在8之后)。
挑战在于:我不能将NewLine用作文本框字符串的一部分。
答案 0 :(得分:0)
您可以在文本框更改时订阅通知,如果有8个字符,则在文本中添加Environment.NewLine。在第一行之后,您必须对文本进行拆分才能获得最后一行,但这并不太难。用户总是可以手动将光标再次移动到行尾,但是你需要添加逻辑来检查行上是否有9个字符并删除最后一个字符。
答案 1 :(得分:0)
最终解决了我的问题,同时考虑到NOT使用Environment.NewLine的限制是增加了一个额外的空间,保存SelectionStart位置,并计算正确的一个而不考虑冗余空间(参见另一篇文章) How to make wordwrap consider a whitespace in a string as a regular character?)
这个解决方案适用于一个非常特殊的情况,我已经创建了自己的“NewLine”供用户使用,当用户点击Alt + Enter时 - 将添加相关空格的数量来填充一行(然后我需要光标向下......这就是问题!):
private void TextBox_OnPreviewKeyDown(object sender, KeyEventArgs e)
{
var tb = sender as TextBox;
if (Keyboard.Modifiers == ModifierKeys.Alt && Keyboard.IsKeyDown(Key.Enter))
{
int origSelectionStart = tb.SelectionStart;
int paddingSpacesAmountToAdd = WidthInCells - (tb.Text.Substring(0, tb.SelectionStart)).Length%WidthInCells;
int origPaddingSpacesAmountToAdd = paddingSpacesAmountToAdd;
// Only if the cursor is in the end of the string - add one extra space that will be removed eventually.
if (tb.SelectionStart == tb.Text.Length) paddingSpacesAmountToAdd++;
string newText = tb.Text.Substring(0, tb.SelectionStart) + new String(' ', paddingSpacesAmountToAdd) + tb.Text.Substring(tb.SelectionStart + tb.SelectionLength);
tb.Text = newText;
int newSelectionPos = origSelectionStart + origPaddingSpacesAmountToAdd;
tb.SelectionStart = newSelectionPos;
e.Handled = true;
}
else if (Keyboard.IsKeyDown(Key.Enter))
{
//source already updated because of the binding UpdateSourceTrigger=PropertyChanged
e.Handled = true;
}
}
这还不够(如上所述 - 存在空格问题),所以:
void _textBox_TextChanged(object sender, TextChangedEventArgs e)
{
int origCursorLocation = _textBox.SelectionStart;
// Regular Whitespace can't be wrapped as a regular character, thus - we'll replace it.
_textBox.Text.Replace(" ", "\u00A0");
_textBox.SelectionStart = origCursorLocation;
}
重要 - 当计算出精确拟合的字体大小时,此解决方案适用于MonoSpace字符。