Некоторое время я работал с rtf-боксом в моем приложении winforms, работающем в качестве интерфейса связи между моим внешним аппаратным устройством и моим ПК через последовательный порт. Проблема, с которой я сталкиваюсь, заключается в том, что при использовании любого примера изменения цвета для выделения текста (который отправляется перед моей фактической командой по последовательному порту), эхо, возвращаемое с моего внешнего устройства, также меняет цвет текста.

Отправив символ ';' Я получаю эхо и ответ от моего устройства, окрашенный в текст.

;;[UART+ERROR]

Мой обработчик события получения является стандартным:

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        //fking threading
        string rxString = serialPort1.ReadExisting();    // running on worker thread

        this.Invoke((MethodInvoker)delegate
        {
            textLog.AppendText(rxString);    // runs on UI thread
        });
    }

Чтобы писать на экран, я использовал приведенный ниже пример (среди многих других, которые я также пробовал), чтобы начать работу в моем приложении. Я не уверен, что делаю неправильно.

    private void AppendTextColor(RichTextBox box, Color color, string text)
    {
        int start = box.TextLength;
        box.AppendText(text);
        int end = box.TextLength;

        // Textbox may transform chars, so (end-start) != text.Length
        box.Select(start, end - start);
        {
            box.SelectionColor = color;
            // could set box.SelectionBackColor, box.SelectionFont too.
        }
        box.SelectionLength = 0; // clear
    }
1
Larry 9 Окт 2014 в 09:52

2 ответа

Лучший ответ

Ваш вызов Select () оставляет свойство SelectionStart в начале добавленного текста, а не в конце текста. Вы можете восстановить его так же, как и для SelectionLength, но более простой способ сделать это:

    private static void AppendTextColor(RichTextBox box, Color color, string text) {
        box.SelectionStart = box.Text.Length;   // Optional
        var oldcolor = box.SelectionColor;
        box.SelectionColor = color;
        box.AppendText(text);
        box.SelectionColor = oldcolor;
    }

Обратите внимание на // Необязательный комментарий, он не нужен, если пользователь не может редактировать текст.

Помните, что в вашем коде есть очень серьезная проблема с пожарным шлангом. Вы вызываете Invoke () с очень высокой частотой, что может привести к тому, что поток пользовательского интерфейса начнет сжигать 100% ядро, когда поле начнет заполняться. Легко сказать, когда это произойдет, вы больше не видите обновлений, и ваша программа перестает отвечать на ввод. Требуется буферизация в обработчике событий DataReceived, использование ReadLine () вместо ReadExisting () обычно является простым способом добиться этого. Вместо этого используйте BeginInvoke (), Invoke () очень может вызвать взаимоблокировку вызова SerialPort.Close ().

2
Hans Passant 12 Окт 2014 в 10:39

Вам необходимо изменить цвет на обычный цвет текста RTB:

box.SelectionStart = box.Text.Length; // clear..
box.SelectionLength = 0; // clear     // ..selection
box.SelectionColor = box.ForeColor;   // reset color
1
TaW 12 Окт 2014 в 10:18