UWP TextBox - 专注于选择
UWP TextBox - Focus on selection
我有一个包含大量文本的 .NET UWP TextBox,我想在其中搜索一个词。当我点击按钮开始搜索时,它会找到这个词的第一次出现。当我再次点击时,它会找到第二个,就像记事本中的 ctrl+f)。
我想专注于找到的世界,但是当文本足够长以致于其中有滚动条时,它不会将找到的单词显示在视图中。
这是此状态下的屏幕截图,展示了我必须如何调整 window 的大小才能看到找到的单词。
这是我的搜索代码(textarea
是 TextBox 类型):
private void Find(string text)
{
textarea.Focus(FocusState.Programmatic);
var start = textarea.SelectionStart + textarea.SelectionLength;
var found = (bool)checkboxFindCaseSensitive.IsChecked ? textarea.Text.IndexOf(text, start) : textarea.Text.IndexOf(text, start, StringComparison.CurrentCultureIgnoreCase);
if (found == -1)
{
textarea.SelectionStart = 0;
found = (bool)checkboxFindCaseSensitive.IsChecked ? textarea.Text.IndexOf(text, start) : textarea.Text.IndexOf(text, start, StringComparison.CurrentCultureIgnoreCase);
if (found == -1) return;
}
textarea.SelectionStart = found;
textarea.SelectionLength = text.Length;
}
我已经尝试将 textarea.Focus(FocusState.Programmatic);
和 textarea.Focus(FocusState.Pointer);
放在方法的末尾,但都没有帮助。
更新:
我发现它对焦正确,但是对焦到最后找到的单词(定位,找到下一个单词之前光标在哪里),而不是当前找到的单词。
所以我需要将焦点更新到当前 SelectionStart
,而不是最后一个。有任何想法吗?我已经尝试再次更改 SelectionStart
,替换文本并更新布局 - 没有任何帮助。
您可以测量文本的高度直到索引,然后相应地调整文本框的大小。
private static float GetTextHeightUntilIndex(TextBox textBox, int index)
{
var height = 0;
var textBuffer = textBox.Text;
// Remove everything after `index` in order to measure its size
textBox.Text = textBuffer.Substring(0, index);
textBox.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
var height = textBox.DesiredSize().Height;
// Put the full text back
textBox.Text = textBuffer;
return height;
}
private void Find(string text)
{
textarea.Focus(FocusState.Programmatic);
var start = textarea.SelectionStart + textarea.SelectionLength;
var found = (bool)checkboxFindCaseSensitive.IsChecked ? textarea.Text.IndexOf(text, start) : textarea.Text.IndexOf(text, start, StringComparison.CurrentCultureIgnoreCase);
if (found == -1)
{
textarea.SelectionStart = 0;
found = (bool)checkboxFindCaseSensitive.IsChecked ? textarea.Text.IndexOf(text, start) : textarea.Text.IndexOf(text, start, StringComparison.CurrentCultureIgnoreCase);
if (found == -1) return;
}
textarea.SelectionStart = found;
textarea.SelectionLength = text.Length;
// -------------------
var cursorPosInPx = GetTextHeightUntilIndex(textarea, found);
// First method: resize your textbox to the selected word
textarea.Height = cursorPosInPx;
// Second method: scroll the textbox
var grid = (Grid)VisualTreeHelper.GetChild(textarea, 0);
for (var i = 0; i <= VisualTreeHelper.GetChildrenCount(grid) - 1; i++)
{
object obj = VisualTreeHelper.GetChild(grid, i);
if (obj is ScrollViewer)
((ScrollViewer)obj).ChangeView(null, cursorPosInPx, null, true);
}
}
但是请注意,对于第一种方法,根据文本框的布局,调整控件的大小可能会产生不需要的效果或根本没有效果。
我有一个包含大量文本的 .NET UWP TextBox,我想在其中搜索一个词。当我点击按钮开始搜索时,它会找到这个词的第一次出现。当我再次点击时,它会找到第二个,就像记事本中的 ctrl+f)。
我想专注于找到的世界,但是当文本足够长以致于其中有滚动条时,它不会将找到的单词显示在视图中。
这是此状态下的屏幕截图,展示了我必须如何调整 window 的大小才能看到找到的单词。
这是我的搜索代码(textarea
是 TextBox 类型):
private void Find(string text)
{
textarea.Focus(FocusState.Programmatic);
var start = textarea.SelectionStart + textarea.SelectionLength;
var found = (bool)checkboxFindCaseSensitive.IsChecked ? textarea.Text.IndexOf(text, start) : textarea.Text.IndexOf(text, start, StringComparison.CurrentCultureIgnoreCase);
if (found == -1)
{
textarea.SelectionStart = 0;
found = (bool)checkboxFindCaseSensitive.IsChecked ? textarea.Text.IndexOf(text, start) : textarea.Text.IndexOf(text, start, StringComparison.CurrentCultureIgnoreCase);
if (found == -1) return;
}
textarea.SelectionStart = found;
textarea.SelectionLength = text.Length;
}
我已经尝试将 textarea.Focus(FocusState.Programmatic);
和 textarea.Focus(FocusState.Pointer);
放在方法的末尾,但都没有帮助。
更新:
我发现它对焦正确,但是对焦到最后找到的单词(定位,找到下一个单词之前光标在哪里),而不是当前找到的单词。
所以我需要将焦点更新到当前 SelectionStart
,而不是最后一个。有任何想法吗?我已经尝试再次更改 SelectionStart
,替换文本并更新布局 - 没有任何帮助。
您可以测量文本的高度直到索引,然后相应地调整文本框的大小。
private static float GetTextHeightUntilIndex(TextBox textBox, int index)
{
var height = 0;
var textBuffer = textBox.Text;
// Remove everything after `index` in order to measure its size
textBox.Text = textBuffer.Substring(0, index);
textBox.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
var height = textBox.DesiredSize().Height;
// Put the full text back
textBox.Text = textBuffer;
return height;
}
private void Find(string text)
{
textarea.Focus(FocusState.Programmatic);
var start = textarea.SelectionStart + textarea.SelectionLength;
var found = (bool)checkboxFindCaseSensitive.IsChecked ? textarea.Text.IndexOf(text, start) : textarea.Text.IndexOf(text, start, StringComparison.CurrentCultureIgnoreCase);
if (found == -1)
{
textarea.SelectionStart = 0;
found = (bool)checkboxFindCaseSensitive.IsChecked ? textarea.Text.IndexOf(text, start) : textarea.Text.IndexOf(text, start, StringComparison.CurrentCultureIgnoreCase);
if (found == -1) return;
}
textarea.SelectionStart = found;
textarea.SelectionLength = text.Length;
// -------------------
var cursorPosInPx = GetTextHeightUntilIndex(textarea, found);
// First method: resize your textbox to the selected word
textarea.Height = cursorPosInPx;
// Second method: scroll the textbox
var grid = (Grid)VisualTreeHelper.GetChild(textarea, 0);
for (var i = 0; i <= VisualTreeHelper.GetChildrenCount(grid) - 1; i++)
{
object obj = VisualTreeHelper.GetChild(grid, i);
if (obj is ScrollViewer)
((ScrollViewer)obj).ChangeView(null, cursorPosInPx, null, true);
}
}
但是请注意,对于第一种方法,根据文本框的布局,调整控件的大小可能会产生不需要的效果或根本没有效果。