Question

I'm displaying hex data in a Rich Text Box, that looks like this:

64 73 67 66 34 33 74 67 35 34 36 79 37 35 79 36
33 67 35 36 67 35 36 33 79 68 34 36 37 38 72 74

and I want it to be displayed with every 3 characters being a different colour. i.e. each bit (2 numbers and a space to be specific) being a different colour.

What I've tried to do is simply set the text colour to blue in designer mode, in order to halve the processing time. Then I'll just change every 2nd 3 characters to red.

However, this is what's happening:

http://i.imgur.com/ZzDtO.png

Here is the code:

for (int i = 0; i < richTextBox1.TextLength; i++)
    if (i % 4 == 1)
    {
        richTextBox1.SelectionStart = i;
        richTextBox1.SelectionLength = 2;
        richTextBox1.SelectionColor = Color.Red;
    }

It's apparent my math is wrong, I just can't think of anything that will work. I've tried i % 3 = 0, selectionLength = 3, and many others.

P.S. If this will be slow, can you suggest any other methods of doing it? here is the full code if you want to see it: http://pastebin.com/vHMfnZW1

Was it helpful?

Solution

I'm not sure I got what you are trying to do (I'm not able to see the images), anyway I'd do it this way:

        for (int i = 3; i < richTextBox1.TextLength; i += 6)
        {
            richTextBox1.SelectionStart = i;
            richTextBox1.SelectionLength = 2;
            richTextBox1.SelectionColor = Color.Red;
        }

EDIT according to your comment.

This is you due to the fact that changing the selection is a slow operation. Things can get better operating on strings and taking advantage that you can set the Rtf property of a RichTextBox. You can inspect the Rtf property of your control after the slow loop to get an idea of what you have to build, it is a string composed by a part defining the fonts and colors used, the actual text, and a simple closing part.

In particular to use blue and red you define this "colour table" {\\colortbl ;\\red0\\green0\\blue255;\\red255\\green0\\blue0;} and then use the codes \\cf1 and \\cf2 for specifying blue and red, respectively.

This code should be much faster:

        StringBuilder sb = new StringBuilder();
        sb.Append("{\\rtf1\\ansi\\ansicpg1250\\deff0\\deflang1050{\\fonttbl{\\f0\\fnil\\fcharset238 Microsoft Sans Serif;}}\r\n{\\colortbl ;\\red0\\green0\\blue255;\\red255\\green0\\blue0;}\r\n\\viewkind4\\uc1\\pard\\f0\\fs17");
        string[] col = new string[] { "\\cf1 ", "\\cf2 " };
        int idxCol = 0;
        for (int i = 0; i < myText.Length; i++)
        {
            if (i % 3 == 0)
            {
                sb.Append(col[idxCol]);
                idxCol = (idxCol + 1) % 2;
            }
            sb.Append(myText[i]);
        }
        sb.Append("\\par\r\n}\r\n");

        richTextBox1.Rtf = sb.ToString();

Please note that I do not know RTF syntax deeply, just the colour part because it's been useful to me in the past. I consider the first and the last part as constant. As you can see the colours are defined as RGB and referenced by the constant string "\cf" followed by the index in the colour table (1 based).

You can find the full specification here and something much simpler but that I found useful here.

OTHER TIPS

Something like this?

for (int i = 0; i < richTextBox1.TextLength; i++)
    var oldStart = richTextBox1.SelectionStart;
    var oldLength = richTextBox1.SelectionLength;
    if (richTextBox1.Text[i-1] == ' ')
    {

        richTextBox1.Select(i);
        richTextBox1.SelectionColor = Color.Red;
    }
    // Restore selection
    richTextBox1.Select(oldStart, oldLength);
}

I was able to figure this out by doing this:

for (int i = 0; i < richTextBox1.TextLength; i++)
{
    if (richTextBox1.Text[i] == ' ')
    {
        if (colourIt == true)
        {
            richTextBox1.SelectionStart = i;
            richTextBox1.SelectionLength = 3;
            richTextBox1.SelectionColor = Color.Red;
            colourIt = false;
        }
        else colourIt = true;

    }
}

Thanks for the help :)

I'm not sure what you're trying to achieve. But maybe this will help:

    for (int i = 0; i < richTextBox1.TextLength; i++)
        if (i % 6 == 2)
        {
            richTextBox1.SelectionStart = i - 2;
            richTextBox1.SelectionLength = 3;
            richTextBox1.SelectionColor = Color.Red;
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top