none
Display Problem: Unicode & RichTextBox

    Question

  • I am having a problem when displaying UTF8 (particularly japanese text) in a RichTextBox.

    When the client displays the text it appears perfect but when I append more text to the RTB it seems the font has changed. Any text after appears to be smaller. I have tried resetting the font to the RTB after a text changed even has fired but it has no effect.


    I am not very good at explaining so here is my cheap mspaint example: click here


    Here are of few pieces of code I am using to process and display the text.

    Connection Class

     

     public delegate void DataArrivalHandler(object sender, string data);

     public event DataArrivalHandler OnDataArrival;


     // Event fired when data arrives 
     OnDataArrival(this, Encoding.UTF8.GetString(buffer, 0, recv));

     


     

    DataArrival event in Parent Form

     

     private void OnDataArrival(object sender, string data)

     {

         string packet = "";

         string[] temp = data.Split(new string[] {"\r\n"}, StringSplitOptions.None);

         int i = 0;

         int x = temp.Length - 1;

         for (i = 0; i < temp.Length; i++)

         {

             last_packet += temp[i];

             if (i < x)

             {

                 if (packet == "")

                     packet = last_packet;

                 else

                     packet += "\r\n" + last_packet;

                 last_packet = "";

             }

         }

         Status s = ((Status)this.ActiveMdiChild);

         s.SetText(packet);

     }

     

     

    Child form w/ RichTextBox

     

     public void SetText(string text)

     {

         if (this.rtbOutput.InvokeRequired)

         {

             SetTextCallback d = new SetTextCallback(SetText);

             this.Invoke(d, new object[] { text });

         }

         else

         {

             if (rtbOutput.Text.Length > 0)

                 rtbOutput.Text += "\r\n" + text;

             else

                 rtbOutput.Text = text;

         }

     }


     private
    void rtbOutput_TextChanged(object sender, EventArgs e)

     {

         rtbOutput.SelectionStart = rtbOutput.Text.Length;

         rtbOutput.ScrollToCaret();
     }

     

     


    Tuesday, August 21, 2007 2:05 AM

Answers

  • I would recommend you use RichTextBox.AppendText() method instead of the += operation, this method would make the caret position automatically be set at the end of the text with the ScrollToCaret effect, meanwhile the newly appended text will be of the default font ignoring the change which cause by the Unicode characters. But we still have to do some more work to avoid the font change after the Unicode characters in the same string added.

    Code Snippet

    public partial class Form7 : Form

        {

            public Form7()

            {

                InitializeComponent();

            }

     

            private void Form7_Load(object sender, EventArgs e)

            {

                text = new string[] {

                    "UserA:aaaaa",

                    "UserB:test Kana こんにちわsome more text",

                    "UserB:test Chinese character 晩上好some more text",

                    "UserA:something here"};

            }

     

            string[] text;

            int index = 0;

     

            private void button1_Click(object sender, EventArgs e)

            {

                //here I mimic the receiving of messages

                string t = "";

                if (index < text.Length)

                {

                    t = text[index++];

     

                   //append text character by character with the default font

                    for (int j = 0; j < t.Length; j++)

                    {

                        //the default font for ascii character is  Microsoft Sans Serif 8.25

                        //the default font for Simplified Chinese is 宋体

                        //the default font for Japanese is MS PGothic

                        this.richTextBox1.SelectionFont = this.richTextBox1.Font;

                        this.richTextBox1.AppendText(t[j].ToString());

                    }

                    this.richTextBox1.AppendText("\r\n");

                    this.richTextBox1.Focus();

                }

            }

        }

     

     

    Monday, August 27, 2007 7:54 AM

All replies

  • Set SelectionFont property of RichTextBox while handling the TextChanged event may solve this problem.

    Friday, August 24, 2007 11:12 AM
  •  

    Thanks for the reply Zhi-Xin Ye,

    This seems to be a partical fix. I do need to figure out how to detect where there unicode characters are in the string so that I may change any characters that appear after them in the same string.

    Basically right now I have

    UserA: <normal size text> 
    UserB: <normal size text><unicode characters><small text>
    UserA: <normal size text>

    SelectionFont

    private void rtbOutput_TextChanged(object sender, EventArgs e)

    {

        rtbOutput.SelectionFont = m_Font;

        rtbOutput.SelectionStart = rtbOutput.Text.Length;

        rtbOutput.ScrollToCaret();

    }

     

     

    Friday, August 24, 2007 7:51 PM
  • I would recommend you use RichTextBox.AppendText() method instead of the += operation, this method would make the caret position automatically be set at the end of the text with the ScrollToCaret effect, meanwhile the newly appended text will be of the default font ignoring the change which cause by the Unicode characters. But we still have to do some more work to avoid the font change after the Unicode characters in the same string added.

    Code Snippet

    public partial class Form7 : Form

        {

            public Form7()

            {

                InitializeComponent();

            }

     

            private void Form7_Load(object sender, EventArgs e)

            {

                text = new string[] {

                    "UserA:aaaaa",

                    "UserB:test Kana こんにちわsome more text",

                    "UserB:test Chinese character 晩上好some more text",

                    "UserA:something here"};

            }

     

            string[] text;

            int index = 0;

     

            private void button1_Click(object sender, EventArgs e)

            {

                //here I mimic the receiving of messages

                string t = "";

                if (index < text.Length)

                {

                    t = text[index++];

     

                   //append text character by character with the default font

                    for (int j = 0; j < t.Length; j++)

                    {

                        //the default font for ascii character is  Microsoft Sans Serif 8.25

                        //the default font for Simplified Chinese is 宋体

                        //the default font for Japanese is MS PGothic

                        this.richTextBox1.SelectionFont = this.richTextBox1.Font;

                        this.richTextBox1.AppendText(t[j].ToString());

                    }

                    this.richTextBox1.AppendText("\r\n");

                    this.richTextBox1.Focus();

                }

            }

        }

     

     

    Monday, August 27, 2007 7:54 AM
  • Thank you Zhi-Xin Ye.

    This does work but I find there to be an issue with the processing time in displaying the text.

    If this was just a file being read it wouldn't be a huge issue but the data is received on the fly and needs to be parsed and displayed instantly.

    Monday, August 27, 2007 7:53 PM
  • Hi,

    I came across the same problem and I ended up fixing it by doing this.

    Don't worry about the AppendText() stuff, doing the AppendText one character at a time isn't very scalable. It doesn't really matter how you get the text in RichTextBox.

    But once you have the text you want to display, just refresh the font by going...

    // rtbMain being my RichTextBox
    rtbMain.Font = new Font(rtbMain.Font.FontFamily, rtbMain.Font.Size, rtbMain.Font.Style);

    Sunday, November 30, 2008 6:18 PM
  • This did it for me:

    private void AppendText(string text)
    {
        if(text == null)
            return;
    
        foreach(char c in text)
        {
            // Avoid double new lines
            if(c != '\r')
                rtbOutput.AppendText(c.ToString(CultureInfo.InvariantCulture));
        }
    }

    Thursday, June 19, 2014 10:34 AM