阻止滚动条在Richtextbox中的位置被更改?

时间:2019-02-12 12:22:46

标签: c# winforms scrollbar richtextbox

我有以下代码:

    private void HighlightSyntax(string syntax)
    {
        Regex regex = null;

        switch (syntax)
        {
            case ".xml":
                regex = new Regex(@"<\/?[^>\/]*>");
                break;
        }

        if (regex != null)
        {
            Input.BeginUpdate();

            // I want to save scrollbar position here and then restore it
            // or maybe even disable it from being changed

            int lastIndex = Input.SelectionStart;
            int lastLength = Input.SelectionLength;

            Input.SelectAll();

            // gets matches
            var matches = regex.Matches(Input.Text).Cast<Match>().ToArray();
            if (matches.Length > 0) // divide into tasks and select all matches
            {
                Color color = Color.ForestGreen;
                int wordsPerTask = 500;
                int tasksAmount = (matches.Length / wordsPerTask) + 1;
                int start = 0;
                int end = matches.Length - 1;

                Task[] tasks = new Task[tasksAmount];
                for (int i = 0; i < tasksAmount; i++)
                { // dividing
                    start = matches.Length / tasksAmount * i;
                    end = matches.Length / tasksAmount * (i + 1) - 1;

                    var start1 = start;
                    var end1 = end;
                    tasks[i] = Task.Run(() => { SelectMatchesInArr(matches, start, end, color); } );
                }

                if (matches.Length - 1 - end > 0)
                    SelectMatchesInArr(matches, end + 1, matches.Length - 1, color);

                Task.WaitAll(tasks);
            }

            Input.Select(lastIndex, lastLength);
            Input.SelectionColor = Color.Black;

            // Restore Input.ScrollBarPosition here

            Input.EndUpdate();
        }
    }

    // selects matches from start to end Indexes with Color color.
    private void SelectMatchesInArr(Match[] matches, int startIndex, int endIndex, Color color)
    {
        for (int i = startIndex; i <= endIndex; i++)
        {
            int selectionStart = Input.SelectionStart;

            lock (_locker)
            {
                Input.Select(matches[i].Index, matches[i].Length);
                Input.SelectionColor = color;

                Input.DeselectAll();
                Input.SelectionStart = selectionStart;
                Input.SelectionLength = 0;
            }
        }
    }

如果正则表达式匹配与该语法相关的任何内容,它将突出显示richtexbox中的语法。一切都奏效,直到我决定将选择分为多个任务。

将选择分为多个任务后,我的滚动条位置不稳定。好吧,我希望它是稳定的,我不希望通过代码对其进行更改。如果我有多个任务在Richtextbox上进行操作,如何防止更改它?在这种情况下我该怎么办?还要检查代码中的注释,它们是为了帮助您解释我要做什么而编写的。

顺便说一下,BeginUpdate()和EndUpdate()方法是从此处获取的扩展方法:Hans Passant's derived from richtextbox class

1 个答案:

答案 0 :(得分:1)

也许最好仅将多线程用于生成匹配项列表,然后将其用于突出显示?

另外,在没有任何同步的情况下在多个线程中修改UI似乎有些危险,因为一个线程可能会在第一个线程设置颜色之前调用“ Input.Select”,而另一个调用“ Input.DeselectAll”。 在一个线程中应用UI更改将消除这种可能性。