zendar
zendar

Reputation: 13562

Display special (non printable) characters in WPF control

I have raw binary data received from device. I would like to display that data something like HEX editors do - display hex values, but also display corresponding characters.

I found fonts that have characters for ASCII codes 0 - 32, but I cannot get them to show on screen.

I tried this with WPF listbox, itemscontrol and textbox.

Is there some setting that can make this work?
Or maybe some WPF control that will show this characters?

Edit:
After some thinking and testing, only characters that make problems are line feed, form feed, carriage return, backspace, horizontal and vertical tab. As quick solution I decided to replace those characters with ASCII 16 (10HEX) character. I tested this with ASCII, UTF-8 and Unicode files and it works with those three formats.

Here is regex that I am using for this:

rawLine = Regex.Replace(inputLine, "[\t\n\r\f\b\v]", '\x0010'.ToString());

It replaces all occurrences of this 6 problematic characters with some boxy sign. It shows that this is not "regular printable" character and it works for me.

Upvotes: 6

Views: 3669

Answers (2)

Transformer
Transformer

Reputation: 7429

This should help you can expand it

    private static string GetPrintableCharacter(char character)
    {
        switch (character)
        {
            case '\a':
            {
                return "\\a";
            }
            case '\b':
            {
                return "\\b";
            }
            case '\t':
            {
                return "\\t";
            }
            case '\n':
            {
                return "\\n";
            }
            case '\v':
            {
                return "\\v";
            }
            case '\f':
            {
                return "\\f";
            }
            case '\r':
            {
                return "\\r";
            }
            default:
            {
                if (character == ' ')
                {
                    break;
                }
                else
                {
                    throw new InvalidArgumentException(Resources.NOTSUPPORTCHAR, new object[] { character });
                }
            }
        }
        return "\\x20";
    }

    public static string GetPrintableText(string text)
    {
        StringBuilder stringBuilder = new StringBuilder(1024);
        if (text == null)
        {
            return "[~NULL~]";
        }
        if (text.Length == 0)
        {
            return "[~EMPTY~]";
        }
        stringBuilder.Remove(0, stringBuilder.Length);
        int num = 0;
        for (int i = 0; i < text.Length; i++)
        {
            if (text[i] == '\a' || text[i] == '\b' || text[i] == '\f' || text[i] == '\v' || text[i] == '\t' || text[i] == '\n' || text[i] == '\r' || text[i] == ' ')
            {
                num += 3;
            }
        }
        int length = text.Length + num;
        if (stringBuilder.Capacity < length)
        {
            stringBuilder = new StringBuilder(length);
        }
        string str = text;
        for (int j = 0; j < str.Length; j++)
        {
            char chr = str[j];
            if (chr > ' ')
            {
                stringBuilder.Append(chr);
            }
            else
            {
                stringBuilder.Append(StringHelper.GetPrintableCharacter(chr));
            }
        }
        return stringBuilder.ToString();
    }

Upvotes: 1

Martin Buberl
Martin Buberl

Reputation: 47114

Not sure if that's excatly what you want, but I would recommend you to have a look in the #develop project. Their editor can display spaces, tabs and end-of-line markers.

I had a quick look at the source code and in the namespace ICSharpCode.AvalonEdit.Rendering the SingleCharacterElementGenerator class, seems to do what you want.

Upvotes: 3

Related Questions