Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在TextSelectionChanged上保留单词索引_C#_Search_Textbox_Selection - Fatal编程技术网

C# 在TextSelectionChanged上保留单词索引

C# 在TextSelectionChanged上保留单词索引,c#,search,textbox,selection,C#,Search,Textbox,Selection,我有一个“查找下一个”和“查找上一个”功能,并对其进行了编辑,这样当用户在文本框中选择文本并单击“查找下一个”或“查找上一个”按钮时,“查找”功能将从所选字符开始索引并遍历每个搜索结果(最初该功能不存在)。要获取所选文本的起始索引,我创建了一个函数: private int GetIntialCharPos(string Text) { int row = Variables._TextBox.GetLineIndexFromCharacterIndex(Variables._TextB

我有一个“查找下一个”和“查找上一个”功能,并对其进行了编辑,这样当用户在文本框中选择文本并单击“查找下一个”或“查找上一个”按钮时,“查找”功能将从所选字符开始索引并遍历每个搜索结果(最初该功能不存在)。要获取所选文本的起始索引,我创建了一个函数:

private int GetIntialCharPos(string Text)
{
    int row = Variables._TextBox.GetLineIndexFromCharacterIndex(Variables._TextBox.CaretIndex);
    int col = Variables._TextBox.CaretIndex - Variables._TextBox.GetCharacterIndexFromLineIndex(row);
    return col;
}
查找下一个和上一个的函数如下所示:

private List<int> _matches;
    private string _textToFind;
    private bool _matchCase;
    private int _matchIndex;

    private void MoveToNextMatch(string textToFind, bool matchCase, bool forward)
    {
        if (_matches == null || _textToFind != textToFind || _matchCase != matchCase)
        {
            int startIndex = 0, matchIndex;
            StringComparison mode = matchCase ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase;

            _matches = new List<int>();
            while (startIndex < Variables._TextBox.Text.Length && (matchIndex = Variables._TextBox.Text.IndexOf(textToFind, startIndex, mode)) >= 0)
            {
                _matches.Add(matchIndex);
                startIndex = matchIndex + textToFind.Length;
            }

            _textToFind = textToFind;
            _matchCase = matchCase;
            _matchIndex = forward ? _matches.IndexOf(GetIntialCharPos(textToFind)) : _matches.IndexOf(GetIntialCharPos(textToFind)) - 1;
        }
        else
        {
            _matchIndex += forward ? 1 : -1;
            if (_matchIndex < 0)
            {
                _matchIndex = _matches.Count - 1;
            }
            else if (_matchIndex >= _matches.Count)
            {
                _matchIndex = 0;
            }
        }

        if (_matches.Count > 0)
        {
            Variables._TextBox.SelectionStart = _matches[_matchIndex];
            Variables._TextBox.SelectionLength = textToFind.Length;
            Variables._TextBox.Focus();
        }
    }
private List\u匹配;
私有字符串\u textToFind;
私人布卢火柴盒;
私有整数匹配索引;
私有void MoveToNextMatch(字符串textToFind、bool matchCase、bool forward)
{
如果(|matches==null | | | | | | | | | | | | | | | | | | | |
{
int startIndex=0,匹配索引;
StringComparison mode=matchCase?StringComparison.CurrentCulture:StringComparison.CurrentCultureInoRecase;
_匹配项=新列表();
而(startIndex=0)
{
_matches.Add(匹配索引);
startIndex=matchIndex+textToFind.Length;
}
_textToFind=textToFind;
_火柴盒=火柴盒;
_matchIndex=forward?\ u matches.IndexOf(GetIntialCharPos(textToFind)):\ u matches.IndexOf(GetIntialCharPos(textToFind))-1;
}
其他的
{
_匹配索引+=正向?1:-1;
如果(_matchIndex<0)
{
_matchIndex=\u matches.Count-1;
}
else if(\u matchIndex>=\u matches.Count)
{
_匹配指数=0;
}
}
如果(_matches.Count>0)
{
变量。_TextBox.SelectionStart=_matches[_matcheindex];
变量。\u TextBox.SelectionLength=textToFind.Length;
变量。_TextBox.Focus();
}
}
我的问题是,一旦用户选择了需要搜索的文本,并通过“查找下一个”和“查找上一个”按钮,然后他决定从不同的索引中选择文本,而不是从选定的索引中继续搜索,它将保持默认的初始顺序,而不是从选定的索引开始,然后遍历该索引的每个结果。我创建了一个小程序,以便您可以更好地查看此问题

如何保留选定的单词索引,以便用户每次从不同的索引中选择时,都可以从用户选择的索引开始搜索,而不是总是从一开始就开始搜索

private int _matchIndex;
这就是你的问题变量。它保留最后一个匹配索引,但您不知道用户何时自己更改它。TextBox类没有SelectionChanged事件来告诉您有关它的信息,因此没有简单的方法来重置变量

只需使用RichTextBox即可,它确实有

但更简单的是,出现此错误是因为您通过将搜索操作拆分为单独的类来添加不必要的状态。状态通常是一件坏事,它是一个bug生成器。通过直接使用TextBox对象,可以轻松地使整个操作无状态:

    private static void MoveToNextMatch(TextBoxBase box, bool forward) {
        var needle = box.SelectedText;
        var haystack = box.Text;
        int index = box.SelectionStart;
        if (forward) {
            index = haystack.IndexOf(needle, index + 1);
            if (index < 0) index = haystack.IndexOf(needle, 0);
        }
        else {
            if (index == 0) index = -1;
            else index = haystack.LastIndexOf(needle, index - 1);
            if (index < 0) index = haystack.LastIndexOf(needle, haystack.Length - 1);
        }
        if (index >= 0) {
            box.SelectionStart = index;
            box.SelectionLength = needle.Length;
        }
        box.Focus();
    }
private static void MoveToNextMatch(TextBoxBase-box,bool-forward){
var指针=box.SelectedText;
var haystack=box.Text;
int index=box.SelectionStart;
如果(转发){
指数=干草堆指数(针,指数+1);
如果(指数<0)指数=haystack.IndexOf(针,0);
}
否则{
如果(索引==0)索引=-1;
else指数=haystack.LastIndexOf(针,指数-1);
如果(指数<0)指数=haystack.LastIndexOf(针,haystack.Length-1);
}
如果(索引>=0){
box.SelectionStart=索引;
box.SelectionLength=针的长度;
}
box.Focus();
}

使用接受StringComparison的最后一个/IndexOf()方法来实现matchCase参数。

我使用的是wpf文本框,有一个selection changed事件可用。但我想这段代码会起作用,因为我假设您编写的代码不需要使用selection changed事件。我退出了,我将对其进行测试,并让您知道我将如何循环搜索结果,即当我到达特定突出显示文本的末尾,并单击“下一步”或“上一步”时,如何重新开始搜索?现在,如果我继续单击“下一步”,它将在最后一个学期结束,如果我单击“上一步”,它将抛出一个索引超出范围的错误。这确实是一个bug,已修复并已包装。