Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 09.04.2016
Сообщений: 2
1

Выделение текста при постоянном добавлении текста в RichTextBox

01.08.2018, 02:38. Просмотров 1169. Ответов 3


Делаю программу которая получает данные по Serial порту и выводит их в RichTextBox. Проблема у меня заключается в том, что когда данные пишутся в RichTextBox я не могу выделить нужный мне текст, так как курсор сразу перемещается в самое начало. Если я отключу соединение, то могу выбрать нужный мне текст. Хотелось бы сделать так, чтобы при получении данных я мог без проблем выделить уже полученный текст. Вывод текста работает по методу сложения строки. Я думаю что проблема заключается в том что при получении данных строка пересоздаётся и заново выводится в RichTextBox , то как сделать иначе я решения так и не нашёл.

C#
1
2
3
4
5
6
7
8
9
10
11
string spReadDataAll;
 
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{          
SerialPort spRead = (SerialPort)sender;
string spReadData = spRead.ReadExisting();
spReadDataAllData += spReadData;
richTextBox1.Invoke(new Action(() => {
richTextBox1.Text = spReadDataAll;
}));
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.08.2018, 02:38
Ответы с готовыми решениями:

Обновление RichTextBox, при добавлении текста
К примеру у меня в RichTextBox загружается файл. Так же есть TextBox1, который добовляет запись...

Как сохранить выделение в RichTextBox текста в при нажатии на Combobox?
Выделяю текст в RichTextBox, хочу поменять его шрифт, а выделение снимается

При добавлении текста в Word часть добавляемого текста сделать жирным
Здравствуйте. Добавляю текст в Word операторами (переменные CalcValue, Str: String формируются...

Выделение текста в RichTextBox
Есть такая задача - в RichTextBox надо выделять определенные слова в красный цвет. Я написал...

__________________
Помогаю в написании курсовых работ и дипломов здесь.
Записывайтесь на профессиональные курсы С#-разработчиков‌
3
553 / 530 / 225
Регистрация: 02.11.2016
Сообщений: 1,538
01.08.2018, 03:29 2
Цитата Сообщение от DualPrince Посмотреть сообщение
Я думаю что проблема заключается в том что при получении данных строка пересоздаётся и заново выводится в RichTextBox , то как сделать иначе я решения так и не нашёл.
В любом случае при обновлении информации в RichTextBox он будет перерисовываться и скидывать выделенный текст. Так что тут без вариантов...

Цитата Сообщение от DualPrince Посмотреть сообщение
spReadDataAllData += spReadData;
Конкатенация строк - далеко не самый лучший вариант. Т.к. память будет съедаться моментально... Если хотите использовать конкатенацию, то используйте лучше StringBuilder, иначе можете столкнуться с проблемой нехватки памяти.

Цитата Сообщение от DualPrince Посмотреть сообщение
Хотелось бы сделать так, чтобы при получении данных я мог без проблем выделить уже полученный текст
Если получение новых строк происходит не очень быстро и каждая строка записывается в текстбокс как новая, могу предложить такой вариант:
C#
1
2
3
4
5
6
7
        private void richTextBox1_DoubleClick(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(richTextBox1.SelectedText))
                return;
            Clipboard.SetText(richTextBox1.SelectedText);
            MessageBox.Show(Clipboard.GetText());
        }
Т.е. при двойном клике на нужной строке (что приводит к выделению строки) она копируется в буфер обмена, откуда уже спокойно может быть извлечена и использована даже если выделение в текстбоксе сброшено. Но при частом обновлении строк способ не сработает...

Добавлено через 2 минуты
При частоте обновления выше 200 мс работает. при меньшем уже практически нет... В идеале, частота обновления должна быть не меньше 500 мс.

Добавлено через 2 минуты
И, разумеется, вместо буфера обмена можно использовать обычную переменную...

Добавлено через 9 минут
Кстати, частоту обновления строк можно искусственно увеличить, записывая новые строки не напрямую в текстбокс, а в List<string> и обновляя строки в текстбоксе при каждой, к примеру, 5-й или 10-й... Ну или по таймеру...
0
706 / 465 / 256
Регистрация: 19.12.2014
Сообщений: 1,783
01.08.2018, 06:10 3
Цитата Сообщение от Shogun31337 Посмотреть сообщение
При частоте обновления выше 200 мс работает. при меньшем уже практически нет... В идеале, частота обновления должна быть не меньше 500 мс.
Ну будет 2 секунды к примеру все равно не поможет. Пока докрутишь список до середины.. он раз и в начало опять прыгнет.
Я бы предложил свой вариант. Нажимаем кнопку Ctrl и вывод перенаправляется в буфер. Пока держите нажатой кнопку Ctrl можно выделять текст и вызывать контекстное меню для копирования. После отпускания Ctrl буфер скидывается в RichTextBox и данные продолжают добавляться напрямую в RichTextBox. И так до следующего нажатия Ctrl.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        RichTextBox text = new RichTextBox();
        Timer timer = new Timer();
        List<string> buffer = new List<string>();
        Random random = new Random();
        ContextMenuStrip menu = new ContextMenuStrip();
        ToolStripMenuItem item1 = new ToolStripMenuItem();
        bool SelectionMode = false;
 
        public Form1()
        {
            InitializeComponent();
 
            KeyPreview = true;
 
            item1.Text = "Копировать";
            menu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { item1 });
            item1.Click += Item1_Click;
 
            text.Location = new System.Drawing.Point(0, 0);
            text.Size = new System.Drawing.Size(ClientSize.Width, ClientSize.Height);
            text.ScrollBars = RichTextBoxScrollBars.Vertical;
            text.ContextMenuStrip = menu;
            Controls.Add(text);
 
            KeyDown += Form1_KeyDown;
            KeyUp += Form1_KeyUp;
 
            timer.Interval = 10;
            timer.Tick += Timer_Tick;
            timer.Enabled = true;
        }
 
        private void Item1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(text.SelectedText))
                return;
            Clipboard.SetText(text.SelectedText);
            MessageBox.Show(Clipboard.GetText());
        }
 
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control == true)
                SelectionMode = true;
        }
 
        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            Trace.WriteLine(e.Control);
            if (SelectionMode && e.Control == false)
            {
                ClearBuffer();
            }
        }
 
        private void Timer_Tick(object sender, System.EventArgs e)
        {
            string RandomLine = $"строка со случаным номером {random.Next(0, 10000)}";
            if (!SelectionMode)
            {
                text.Text = text.Text + "\n" + RandomLine;
            }
            else
                buffer.Add(RandomLine);
        }
 
        private void ClearBuffer()
        {
            foreach (string s in buffer)
                text.Text = text.Text + "\n" + s;
            timer.Enabled = false;
            buffer.Clear();
            SelectionMode = false;
            timer.Enabled = true;
        }
    }
}
Код простой proof of concept
1
553 / 530 / 225
Регистрация: 02.11.2016
Сообщений: 1,538
01.08.2018, 06:49 4
Цитата Сообщение от HectorPrima Посмотреть сообщение
Ну будет 2 секунды к примеру все равно не поможет. Пока докрутишь список до середины.. он раз и в начало опять прыгнет.
Тут расчет был на то, что в текстбоксе будет автоскролл и на виду будут последние значения, которые, собственно, и представляют интерес... Если нужно по списку перемещаться, то, конечно, ничего не получится. Согласен.

Цитата Сообщение от HectorPrima Посмотреть сообщение
Я бы предложил свой вариант. Нажимаем кнопку Ctrl и вывод перенаправляется в буфер.
Интересное решение! Поддерживаю!

Добавлено через 4 минуты
Цитата Сообщение от HectorPrima Посмотреть сообщение
Пока держите нажатой кнопку Ctrl можно выделять текст и вызывать контекстное меню для копирования. После отпускания Ctrl буфер скидывается в RichTextBox и данные продолжают добавляться напрямую в RichTextBox. И так до следующего нажатия Ctrl.
Тогда, на мой взгляд, удобнее было бы не при нажатом Ctrl это делать, а контролом переключать назначение вывода. Т.е. раз нажал - вывод в текстбокс прекратился и можно спокойно выделять, еще раз нажал - вывод идет в текстбокс. Ну, это мое личное мнение. Мне бы так удобнее было. Но, как говорится, на вкус и цвет все фломастеры разные.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.08.2018, 06:49

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь или здесь.

Простое выделение текста в RichTextBox
Здравствуйте уважаемые форумчани! Необходимо с использованием средств C# просто выделить...

Поиск и выделение текста в RichTextBox
Приветствую. На форме есть RichTextBox1 и кнопка Button1. Так же имеется файл words.txt,...

Выделение текста разным цветом в RichTextBox
Написал функцию, входными параметрами которой является строка, которая должна быть добавлена в...

Выделение текста в richTextBox из другой формы
проблема такова: имеется form1 и form2. form2 - диалоговое окно, в котором задается строка и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.