如何重构这个方法C#Window

时间:2009-10-01 09:29:19

标签: c# winforms richtextbox

我有一个TextBox来搜索RichTextBox Control中输入文本的所有出现。 搜索结束后,结果将填充在遍历pupose的列表框中。

我已经编写了以下功能来实现所需的结果..但是需要花费大量的时间才能完成..我需要一些建议来解决这个问题

简而言之,我需要实现FindAll功能..

public void FindSearchResults(string searchWord)
{
    CheckState matchCase = default(CheckState);
    CheckState matchWholeWords = default(CheckState);
    RichTextBox tvc = this._rt;
    List<string> retVal = new List<string>();
    RichTextBoxFinds FindOptions = default(RichTextBoxFinds);

    currentSearchWord = searchWord;
    FindOptions = RichTextBoxFinds.None;
    // Location to begin the search. 
    FindOptions = RichTextBoxFinds.None;

    int searchResult = -2;
    int start = 0;
    string expandedValue = "";
    if ((matchWholeWords == CheckState.Checked) & (matchCase == CheckState.Checked))
    {
        FindOptions = RichTextBoxFinds.MatchCase | RichTextBoxFinds.WholeWord;
    }
    else if ((matchWholeWords == CheckState.Checked))
    {
        FindOptions = RichTextBoxFinds.WholeWord;
    }
    else if ((matchCase == CheckState.Checked))
    {
        FindOptions = RichTextBoxFinds.MatchCase;
    }
    else
    {
        FindOptions = RichTextBoxFinds.None;
    }
    while (searchResult != -1 & start < tvc.Text.Length)
    {
        searchResult = tvc.Find(searchWord, start, FindOptions);
        if ((searchResult != -1))
        {
            expandedValue = Expand(searchWord, searchResult);
            while (searchResultList.ContainsKey(expandedValue))
            {
                // just to keep uniqueness 
                expandedValue = expandedValue + " ";
            }

            retVal.Add(expandedValue);
            searchResultList[expandedValue] = searchResult;
            start = searchResult + searchWord.Length;
        }
    }

}

private string Expand(string searchWord, int searchResult)
{
    string retVal = null;
    int startPos = 0;
    int endPos = 0;
    int spaceCount = 0;
    RichTextBox tvc = this._rt;

    startPos = searchResult;
    spaceCount = 0;
    while (spaceCount < 2 & startPos > 0)
    {
        startPos = startPos - 1;
        char[] ch=tvc.Text.Substring(startPos,1).ToCharArray();
        if (ch[0] == (Char)32)
        {
            spaceCount = spaceCount + 1;
        }
    }

    spaceCount = 0;
    endPos = searchResult + 1;

    while (spaceCount < 4 & endPos < tvc.Text.Length)
    {
        int asciiVal = 0;
        asciiVal = Strings.Asc(tvc.Text.Substring(endPos,1));
        if (asciiVal == 10 | asciiVal == 13 | asciiVal == 32)
        {
            spaceCount = spaceCount + 1;
        }
        endPos = endPos + 1;
    }

    retVal = tvc.Text.Substring(startPos, endPos - startPos);
    retVal = retVal.Replace(Environment.NewLine, string.Empty);
    return retVal;
} 

2 个答案:

答案 0 :(得分:0)

恕我直言,你的代码目前还不是很清楚。首先,我会:

  • 在确定搜索参数的位之间进行明确划分
  • 执行实际搜索(此方法不应引用任何UI组件)
  • 显示结果

至少(至少对我来说)你的方法在做什么并不明显。 Expand方法在做什么?为什么使用编辑框?

答案 1 :(得分:0)

这段代码不是最干净的,绝对可以使用重构,但我认为你应该看一下在搜索文本时以块的形式执行Find方法。此外,当你正在寻找像''那样的停止字符时,你应该搜索块。我的查询似乎对Find方法运行得非常快。

private void FindButton_Click(object sender, EventArgs e)
    {
        findOptions = default(RichTextBoxFinds);
        resultsListBox.Items.Clear();

        if (MatchCaseCheckBox.Checked)
        {
            findOptions = findOptions | RichTextBoxFinds.MatchCase;
        }

        if (MatchEntireWordCheckBox.Checked)
        {
            findOptions = findOptions | RichTextBoxFinds.WholeWord;
        }

        int[] foundLocations = FindSearchResults(TextToSearchTextBox.Text.Trim());
        string[] words = null;
        if (foundLocations.Length > 0)
        {
            words = GetWords(foundLocations);

        }
        foreach (string word in words)
        {
            resultsListBox.Items.Add(word);
        }
    }

    private string[] GetWords(int[] foundLocations)
    {
        string textChunk = string.Empty;
        int chunkSize = 64;
        int textLength = MyRichTextBox.TextLength;
        int startIndex = 0;
        int endIndex = 0;
        List<string> words = new List<string>();
        int lastSpaceIndex = -1;
        int firstSpaceIndex = -1;
        foreach (int location in foundLocations)
        {
            textChunk = string.Empty;
            startIndex = location;
            endIndex = location;
            firstSpaceIndex = -1;
            lastSpaceIndex = -1;

            //get the start index.
            while (startIndex >= 0)
            {
                if (startIndex - chunkSize >= 0)
                {
                    startIndex -= chunkSize;
                }
                else
                {
                    startIndex -= Math.Abs(startIndex);
                }

                textChunk += MyRichTextBox.Text.Substring(startIndex, location - startIndex);
                firstSpaceIndex = textChunk.LastIndexOf(' ');
                if (firstSpaceIndex > -1)
                {
                    firstSpaceIndex = location - (textChunk.Length - firstSpaceIndex);
                    break;
                }
            }
            textChunk = string.Empty;
            startIndex = location;
            if (firstSpaceIndex == -1)
            {
                firstSpaceIndex = 0;
            }

            while (textChunk.Length <= textLength)
            {
                if (chunkSize + location < textLength)
                {
                    endIndex = chunkSize;
                }
                else
                {
                    endIndex = (textLength - startIndex);
                }

                textChunk += MyRichTextBox.Text.Substring(firstSpaceIndex + 1,
                    endIndex);
                lastSpaceIndex = textChunk.IndexOf(' ');
                if (lastSpaceIndex > -1)
                {
                    words.Add(textChunk.Substring(0, lastSpaceIndex));
                    break;
                }
            }
        }
        return words.ToArray();
    }

    private int[] FindSearchResults(string textToSearchFor)
    {

        int textLength = MyRichTextBox.TextLength;
        int chunkSize = 128;
        int startIndex = 0;
        int endIndex = 0;
        int foundIndex = -1;
        List<int> foundLocations = new List<int>();

        while (startIndex < textLength)
        {
            if ((chunkSize + startIndex) < textLength)
            {
                endIndex += chunkSize;
            }
            else
            {
                endIndex += textLength - endIndex;
            }

            foundIndex = MyRichTextBox.Find(textToSearchFor, startIndex, endIndex, findOptions);
            if (foundIndex > -1)
            {
                foundLocations.Add(foundIndex);
            }
            startIndex += chunkSize;
        }

        return foundLocations.ToArray();
    }