【问题标题】:TextBox Indexof and LastIndexOfTextBox Indexof 和 LastIndexOf
【发布时间】:2015-03-24 17:57:20
【问题描述】:

因为 TextBox 没有查找功能,所以我根据需要创建并修改了自己的版本。我已经创建了函数。一个用于Search Next,另一个用于Search Previous

我的问题是:

  1. 如果我的搜索词超过 1 个字符并且我已经搜索过 学期四次,如果在第四学期我决定点击 搜索上一个它会返回到上一个搜索词,并且 工作正常。现在因为我之前点击了 4 次搜索,我 如果我决定去 第四学期再次使用查找下一个,我必须双击查找下一个 然后它选择第 4 个术语。

  2. 如果我的搜索词是 1 个字符长并且我想搜索一个 字符,我输入字符,例如'o' 它通过每个 文本框中的字符,但一旦我决定使用搜索返回 以前,我必须双击搜索上一个按钮,然后它 返回,如果我决定下一步搜索,我必须双击 然后它会搜索下一个。

这可能有助于理解双击和单击:

http://media.giphy.com/media/3xz2BJgF2DrtcCnP1e/giphy.gif

我一直试图让它工作很长一段时间,但我没有运气。我不知道我要去哪里,在我困惑之前,如果有人可以帮助我,那就太好了。

我的代码:

变量

public int startPostion = 0;
boolean passedNext;
public int pos = 0;

搜索下一个

 public bool FindAndSelectNext(string TextToFind, bool MatchCase)
    {
        try
        {
            var mode = MatchCase ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase;
            int position = TheTextBox.Text.IndexOf(TextToFind, startPostion, mode);
            pos = position;

            if (position == -1)
            {
                var TheString = TheTextBox.Text;
                var foundposition2 = TheString.IndexOf(TextToFind, mode);

                TheTextBox.SelectionStart = foundposition2;
                TheTextBox.SelectionLength = TextToFind.Length;
                startPostion = foundposition2 + TextToFind.Length;
                TheTextBox.Focus();

                passedNext = false;
                Debug.WriteLine("1");
                return true;

            }
            else
            {
                TheTextBox.SelectionStart = position;
                TheTextBox.SelectionLength = TextToFind.Length;
                startPostion = position + TextToFind.Length;
                TheTextBox.Focus();

                passedNext = true;
                Debug.WriteLine("2");
                return true;
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show(string.Format("Could not find '{0}' in the document.", TextToFind), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        return true;
    }

搜索上一个

public bool FindAndSelectPrevious(string TextToFind, bool MatchCase)
    {
        StringComparison mode = MatchCase ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase;
        if (passedNext == true)
        {
            int foundPosition = startPostion < 0 ? TheTextBox.Text.Length : startPostion - 1;
            foundPosition = TheTextBox.Text.LastIndexOf(TextToFind, pos, mode);
            passedNext = false;
            if (foundPosition < 0)
            {
                if (startPostion < 0)
                {
                    MessageBox.Show(string.Format("Could not find '{0}' in the document.", TextToFind), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return false;
                }
                foundPosition = TheTextBox.Text.LastIndexOf(TextToFind, mode);
                Debug.WriteLine("1p");
            }

            TheTextBox.SelectionStart = foundPosition;
            TheTextBox.SelectionLength = TextToFind.Length;
            startPostion = foundPosition;
            TheTextBox.Focus();
            Debug.WriteLine("2p");
            passedNext = false;
        }
        else
        {
            int foundPosition = startPostion < 0 ? TheTextBox.Text.Length : startPostion;
            foundPosition = TheTextBox.Text.LastIndexOf(TextToFind, foundPosition, mode);

            if (foundPosition < 0)
            {
                if (startPostion < 0)
                {
                    MessageBox.Show(string.Format("Could not find '{0}' in the document.", TextToFind), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return false;
                }
                foundPosition = TheTextBox.Text.LastIndexOf(TextToFind, mode);
            }

            if (!(foundPosition == -1))
            {
                try
                {
                    int foundPositionz = startPostion < 0 ? TheTextBox.Text.Length : startPostion - 1;
                    foundPositionz = TheTextBox.Text.LastIndexOf(TextToFind, foundPositionz, mode);

                    TheTextBox.SelectionStart = foundPositionz;
                    TheTextBox.SelectionLength = TextToFind.Length;
                    startPostion = foundPositionz;
                    TheTextBox.Focus();
                }
                catch (Exception ex)
                {
                    var TheString = TheTextBox.Text;
                    var foundposition2 = TheString.LastIndexOf(TextToFind, mode);

                    TheTextBox.SelectionStart = foundposition2;
                    TheTextBox.SelectionLength = TextToFind.Length;
                    startPostion = foundposition2;
                    TheTextBox.Focus();
                    Debug.WriteLine("12p");
                }
            }
            else
            {
                MessageBox.Show(string.Format("Could not find '{0}' in the document.", TextToFind), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }
        return true;
    }

【问题讨论】:

  • 您需要做的是,当您从一个搜索更改为另一个搜索时,按搜索词的长度递增或递减 StartPosition。他们只是使 FindAndSelectPrevious 与其他搜索功能相反。
  • @Pedro.The.Kid 感谢您的快速响应,但我不明白您所说的递增或递减 startPosition 是什么意思?介意详细说明吗?
  • 进行搜索之前的第一件事 if() startPostion += TextToFind.Length
  • 你为什么使用dynamic
  • @Dai 它只是将代码从 vb.net 转换为 C#。我会解决的。

标签: c# textbox indexof lastindexof


【解决方案1】:

恕我直言,您应该在用户第一次尝试查找某些内容时找到所有匹配项,然后保留一个指示要选择/突出显示的匹配项的索引。

例如:

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();
        while (startIndex < TheTextBox.Text.Length &&
            (matchIndex = TheTextBox.Text.IndexOf(textToFind, startIndex, mode)) >= 0)
        {
            _matches.Add(matchIndex);
            startIndex = matchIndex + textToFind.Length;
        }

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

    if (_matches.Count > 0)
    {
        TheTextBox.SelectionStart = _matches[_matchIndex];
        TheTextBox.SelectionLength = textToFind.Length;
        TheTextBox.Focus();
    }
    else
    {
       MessageBox.Show(string.Format(
           "Could not find '{0}' in the document.", TextToFind),
           ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);

    }
}

public bool FindAndSelectNext(string textToFind, bool matchCase)
{
    MoveToNextMatch(textToFind, matchCase, true);
}

public bool FindAndSelectPrevious(string textToFind, bool matchCase)
{
    MoveToNextMatch(textToFind, matchCase, false);
}

【讨论】:

  • 这太棒了!但是我确实还有一个问题,如果我添加新文本,我如何重新初始化列表以检测更改。现在它只搜索在没有用户的情况下添加的文本。如果我添加更多文本并尝试搜索,它将不会通过它们。是否需要将任何代码添加到 TextBox 的 textchanged 事件中以检测更改以便重新初始化?
  • 当然。您可以轻松修改上述示例以满足您的需要。例如,您只需将_matches 字段设置为null,即可使当前缓存的搜索结果无效。下次调用其中一种搜索方法时,将根据最新文本重新创建它。以上内容并非旨在完全实现您拥有的任何规范(怎么可能,因为我们没有完整的规范?:))......这只是展示基本技术的一种方式。
  • 感谢它的工作,这正是我想要的工作方式。对不起,我花了很长时间来测试代码,否则它会是一个即时的答案! ;)
  • @PeterDuniho 我知道这是很久以前的事了,但我想知道你是否还能帮我做点什么。这非常有效,但是,当我找到文本时,它会跳转到文本第一次出现的开头,然后遍历所有内容。有没有办法从字符的当前索引开始搜索并通过?这个 GIf 解释了这一切,recordit.co/W3Hw7ORKFq
  • “有没有办法从字符的当前索引开始搜索并遍历”——这是编程。总有办法的。在这种情况下,请注意_matches 数组只是存储字符索引。因此,您可以在初始匹配时,在初始化 _matches 数组后,扫描该数组以查找值大于字符当前索引的第一个元素,并将 _matchIndex 设置为该元素的索引。如果您在实施该想法时遇到困难,请发布一个新问题,而不是使用 cmets 尝试提出问题。
猜你喜欢
  • 2020-03-30
  • 2015-01-11
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 2018-12-16
相关资源
最近更新 更多