C# Отображение суррогатной пары (символа с кодом >FFFF)
Известно, что внутренний формат строк в .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, для которой ждать патчей, понятное дело, не приходится.Главное, не забывать про то, что шрифт надо задавать до вставки/присвоения символа.
Обсуждение на Киберфоруме Копия
Пример
Пример на GitHub
Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2018/03/16/c-ot