Известно, что внутренний формат строк в .NET — UTF16, что значит, что символы из основной многоязыковой плоскости (BMP) Unicode, т.е. с кодом меньше FFFF кодируются одним машинным словом, а остальные символы — двумя, одно из которых т.н. суррогат.
Так вот, как оказалось, с отображением суррогатных пар может возникнуть проблема. Контролы Windows Forms могут воспринимать символ с кодом >FFFF не как один символ, как должно быть, а как два. Для примера пробуем отобразить анатолийский иероглиф
с кодом 0x14476
Как видно, TextBox
и Label
воспринимают символ, как два символа, и, соответственно, его не отображают, а RichTextBox
видит, что это один символ, но не отображает его, даже при правильно заданном шрифте.
MessageBox
также отображает символ не как один, а как два:
Для устранения проблемы с RichTextBox
достаточно задать нужный шрифт перед тем, как присвоить свойству Text
нужные символы.
int Code = 0x14476; //анатолийский иероглиф Font AnFont = new Font("Anatolian", 24, FontStyle.Regular, GraphicsUnit.Pixel, 1); private void Form1_Load(object sender, EventArgs e) { string strSP = char.ConvertFromUtf32(Code); lblTest.Font = AnFont; txtTest.Font = AnFont; lblFont.Text = AnFont.FontFamily.Name; rtbTest.Font = AnFont; lblTest.Text = strSP; txtTest.Text = strSP; rtbTest.Text = strSP; }
PictureBox
также отрисовывает нужный символ без проблем:
А корень проблемы кроется не в C#, .NET и компонентах Windows Forms, а в самой Windows. Пакет обновления SP1 для Windows 7 решает проблему полностью.
Наиболее универсальным решением является использование RichTextBox
для работы с такими символами, во всяком случае, это работает даже для Windows XP, для которой ждать патчей, понятное дело, не приходится.
Главное, не забывать про то, что шрифт надо задавать до вставки/присвоения символа.