防止在richtextbox中更改滚动条位置?

问题描述 投票:0回答:1

我有以下代码:

    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;
            }
        }
    }

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

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

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

c# winforms scrollbar richtextbox
1个回答
1
投票

也许最好只使用多线程来生成匹配列表然后用它们来突出显示? 此外,在没有任何同步的情况下修改多个线程中的UI似乎有点危险,因为一个线程可能会调用'Input.Select'而另一个线程可能会在第一个线程设置颜色之前调用'Input.DeselectAll'。在一个线程中应用UI更改将消除这种可能性。

© www.soinside.com 2019 - 2024. All rights reserved.