简介:本文深入探讨C#实现竖排文字显示的三种技术方案,涵盖WinForms、WPF和图像处理三大场景,提供完整代码示例和性能优化建议,帮助开发者解决中文排版、动态调整等实际问题。
竖排文字作为东亚传统排版方式,在古籍、书法、日式UI等场景中具有不可替代性。C#作为主流开发语言,实现竖排显示需解决字符旋转、布局计算、动态调整三大核心问题。根据实际应用场景,可将需求分为三类:
WinForms方案适合传统桌面应用,WPF方案提供更丰富的视觉效果,图像处理方案则适用于特殊场景。开发者需根据项目需求选择合适的技术路线。
protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;string text = "竖排文字示例";Font font = new Font("微软雅黑", 16);Brush brush = Brushes.Black;// 计算绘制区域SizeF textSize = g.MeasureString(text, font);float x = 50;float y = 50;float charWidth = textSize.Height; // 旋转后高度变宽度float charHeight = textSize.Width; // 旋转后宽度变高度// 逐个字符绘制for (int i = 0; i < text.Length; i++){// 保存当前状态GraphicsState state = g.Save();// 移动到字符位置g.TranslateTransform(x + i * charWidth, y);// 旋转90度(顺时针)g.RotateTransform(90);// 绘制字符(注意坐标调整)g.DrawString(text[i].ToString(), font, brush, 0, 0);// 恢复状态g.Restore(state);}}
技术要点:
TranslateTransform和RotateTransform实现坐标变换
public class VerticalLabel : Control{private string _text = "竖排文本";public override string Text{get => _text;set{_text = value;Invalidate();}}protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);using (Graphics g = e.Graphics){using (Font font = new Font("宋体", 14)){float x = 10;float y = Height - 10; // 从底部开始for (int i = 0; i < _text.Length; i++){// 计算字符位置(从下往上)SizeF size = g.MeasureString(_text[i].ToString(), font);y -= size.Height;// 绘制单个字符g.DrawString(_text[i].ToString(), font, Brushes.Black, x, y);}}}}}
优化建议:
<TextBlock FontSize="20" Text="WPF竖排示例"><TextBlock.LayoutTransform><RotateTransform Angle="90"/></TextBlock.LayoutTransform></TextBlock>
特点:
public class VerticalTextPanel : ItemsControl{protected override void PrepareContainerForItemOverride(DependencyObject element, object item){base.PrepareContainerForItemOverride(element, item);if (element is ContentPresenter presenter){presenter.LayoutTransform = new RotateTransform(90);// 调整边距实现垂直排列presenter.Margin = new Thickness(0, 10, 0, 0);}}}
XAML使用示例:
<local:VerticalTextPanel><sys:String>第</sys:String><sys:String>一</sys:String><sys:String>行</sys:String></local:VerticalTextPanel>
public static WriteableBitmap RenderVerticalText(string text, int width, int height){var bitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Pbgra32, null);try{bitmap.Lock();// 使用FormattedText实现精确排版var formattedText = new FormattedText(text,CultureInfo.CurrentCulture,FlowDirection.LeftToRight,new Typeface("微软雅黑"),16,Brushes.Black);// 逐个字符绘制(需实现旋转逻辑)// ...(具体实现略)}finally{bitmap.Unlock();}return bitmap;}
适用场景:
public static Bitmap CreateVerticalTextImage(string text, Font font, Size size){Bitmap bmp = new Bitmap(size.Width, size.Height);using (Graphics g = Graphics.FromImage(bmp)){g.Clear(Color.White);g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;float x = 20;float y = size.Height - 20; // 从底部开始for (int i = 0; i < text.Length; i++){// 计算字符位置SizeF charSize = g.MeasureString(text[i].ToString(), font);y -= charSize.Height;// 绘制字符g.DrawString(text[i].ToString(), font, Brushes.Black, x, y);}}return bmp;}
性能优化:
public static SKBitmap CreateVerticalTextWithSkia(string text, SKFont font, int width, int height){var info = new SKImageInfo(width, height);using (var surface = SKSurface.Create(info)){var canvas = surface.Canvas;canvas.Clear(SKColors.White);float x = 20;float y = height - 20;using (var paint = new SKPaint{Color = SKColors.Black,IsAntialias = true,Typeface = SKTypeface.FromFamilyName(font.FamilyName)}){foreach (char c in text){// 测量字符尺寸paint.TextSize = font.Size;float charWidth = paint.MeasureText(c.ToString());// 调整位置y -= charWidth;// 绘制字符canvas.DrawText(c.ToString(), x, y, paint);}}return surface.Snapshot();}}
优势:
症状:部分中文字符显示不全或乱码
解决方案:
FlowDirection="RightToLeft"配合旋转优化建议:
技术方案:
// 示例:横竖混合排版public void DrawMixedText(Graphics g){// 横排文本g.DrawString("横排文本", new Font("宋体", 16), Brushes.Black, 10, 10);// 竖排文本string verticalText = "竖排文本";float x = 100;float y = 50;for (int i = 0; i < verticalText.Length; i++){g.SaveState();g.TranslateTransform(x, y + i * 20);g.RotateTransform(90);g.DrawString(verticalText[i].ToString(), new Font("宋体", 16), Brushes.Black, 0, 0);g.RestoreState();}}
通过本文介绍的多种技术方案,开发者可以根据具体项目需求选择最适合的实现方式。从简单的WinForms绘制到复杂的WPF布局,再到跨平台的图像处理方案,C#提供了丰富的工具集来实现高质量的竖排文字显示效果。