• [C#] StringFormat详解之文本方向、对齐


    在使用GDI方式处理文本时,往往会用到StringFormat。里面的某些点有点反直觉,不够直观,所以本篇就通过图文的方式去讲解一下。

    本篇内容仅涉及到文本方向、对齐的相关内容。

    如有错误、不妥之处,欢迎大家指正。

    一、相关属性

    与文本方向、对齐相关的属性,主要与三个属性有关:

    Alignment、LineAlignment、FormatFlags。

    Alignment与LineAlignment的属性值都是StringAlignment枚举。StringAlignment枚举有三个成员:Near、Center、Far。其MSDN解释如下:

    FormatFlags的属性值是StringFormatFlags枚举。主要与其枚举的两个成员——DirectionRightToLeft、DirectionVertical——有关。其MSDN解释如下:

    二、使用搭配

    1,现代文的阅读顺序:水平方向上从左到右、从上到下。

    此时,FormatFlags不包含成员DirectionRightToLeft、DirectionVertical。

    1.1,对于Alignment,其示意图如下:

    此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:

    Near:左对齐

    Center:居中对齐

    Far:右对齐

    1.2,对于LineAlignment,其示意图如下:

    此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:

    Near:文本段落处于显示区域顶部

    Center:文本段落处于显示区域中部

    Far:文本段落处理显示区域底部

    1.3,Alignment和LineAlignment的组合共有9种,如下所示:

     

    2,古文的阅读顺序:垂直方向上从上到下、从右到左。 

    此时,FormatFlags同时包含成员DirectionRightToLeft、DirectionVertical。

    2.1,对于Alignment,其示意图如下:

    此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:

    Near:顶部对齐

    Center:居中对齐

    Far:底部对齐

    2.2,对于LineAlignment,其示意图如下:

    此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:

    Near:文本段落处于显示区域右侧

    Center:文本段落处于显示区域中侧

    Far:文本段落处理显示区域左侧

    2.3,Alignment和LineAlignment的组合共有9种,如下所示:

     

    3,其他

    除上文两种搭配方式之外,还有两种搭配方式,即分别使用DirectionRightToLeft和DirectionVertical,这两种搭配方式共有18种样式,不过日常几乎用不到。具体想查看可以通过文末提供的示例源代码自行查看。

     示例程序截图:

    三、重点说明

    仅搭配使用而言,并没有什么可多说的,直接使用即可,但是如果想在某个具体的区域内显示文本段落的话——比如上面的示例截图,其坐标的计算是个难点。

    这里的“坐标”并不是人眼看上去的坐标,而是使用Graphics.DrawString时所使用的坐标——绘制文本的左上角。

    下面进行举例说明。

    例1,现代文方式、右对齐、居中显示。

     示意图如下所示(这个示意图是用GDI画的,其中绿框是后期为了方便讲解而手动加的):

    其中:

    显示区域(上图的蓝色方框):宽=高=200

    文本区域:即字符串所占的矩形区域(上图中绿色方框):宽:165,高:43

    此时,在使用DrawString时,其point(绘制文本的左上角)的坐标并不是绿色方框的左上角:X:200-165=35,Y:(200-43)/2=78(此处取整数)

    其坐标应该是:X:200,Y:200/2=100,即下图中红点所在的坐标(其中黄线是中线):

    是不是很反直觉?

    不过当接受了这种坐标计算思路之后,一切就迎刃而解了。

    下面再举一个例子:

    例2:古文方式、底部对齐、左侧显示

    示意图如下所示(这个示意图是用GDI画的,其中绿框是后期为了方便讲解而手动加的):

    其中:

    显示区域(上图的蓝色方框):宽=高=200

    文本区域:即字符串所占的矩形区域(上图中绿色方框):宽:43,高:165

    此时,在使用DrawString时,其point(绘制文本的左上角)的坐标并不是绿色方框的左上角:X:0,Y:200-165=35

    其坐标应该是:X:0,Y:200,即下图中红点所在的坐标:

    四、坐标计算核心代码

    完整代码见下方提供的源工程。

      1 //……
      2 
      3 Bitmap bmpStr = new Bitmap(200,200);
      4 PointF stringStart = new PointF(0, 0);
      5 
      6 if (!DirectionRightToLeft)
      7 {
      8     if (!DirectionVertical)
      9     {
     10         if (alignment == StringAlignment.Near)
     11         {
     12             stringStart.X = 0;
     13         }
     14         else if (alignment == StringAlignment.Center)
     15         {
     16             stringStart.X = bmpStr.Width / 2;
     17         }
     18         else if (alignment == StringAlignment.Far)
     19         {
     20             stringStart.X = bmpStr.Width;
     21         }
     22 
     23         if (lineAlignment == StringAlignment.Near)
     24         {
     25             stringStart.Y = 0;
     26         }
     27         else if (lineAlignment == StringAlignment.Center)
     28         {
     29             stringStart.Y = bmpStr.Height / 2;
     30         }
     31         else if (lineAlignment == StringAlignment.Far)
     32         {
     33             stringStart.Y = bmpStr.Height;
     34         }
     35     }
     36     else
     37     {
     38         if (alignment == StringAlignment.Near)
     39         {
     40             stringStart.Y = 0;
     41         }
     42         else if (alignment == StringAlignment.Center)
     43         {
     44             stringStart.Y = bmpStr.Height / 2;
     45         }
     46         else if (alignment == StringAlignment.Far)
     47         {
     48             stringStart.Y = bmpStr.Height;
     49         }
     50 
     51         if (lineAlignment == StringAlignment.Near)
     52         {
     53             stringStart.X = 0;
     54         }
     55         else if (lineAlignment == StringAlignment.Center)
     56         {
     57             stringStart.X = bmpStr.Width / 2;
     58         }
     59         else if (lineAlignment == StringAlignment.Far)
     60         {
     61             stringStart.X = bmpStr.Width;
     62         }
     63     }
     64 }
     65 else
     66 {
     67     if (!DirectionVertical)
     68     {
     69         if (alignment == StringAlignment.Near)
     70         {
     71             stringStart.X = bmpStr.Width;
     72         }
     73         else if (alignment == StringAlignment.Center)
     74         {
     75             stringStart.X = bmpStr.Width / 2;
     76         }
     77         else if (alignment == StringAlignment.Far)
     78         {
     79             stringStart.X = 0;
     80         }
     81 
     82         if (lineAlignment == StringAlignment.Near)
     83         {
     84             stringStart.Y = 0;
     85         }
     86         else if (lineAlignment == StringAlignment.Center)
     87         {
     88             stringStart.Y = bmpStr.Height / 2;
     89         }
     90         else if (lineAlignment == StringAlignment.Far)
     91         {
     92             stringStart.Y = bmpStr.Height;
     93         }
     94     }
     95     else
     96     {
     97         if (alignment == StringAlignment.Near)
     98         {
     99             stringStart.Y = 0;
    100         }
    101         else if (alignment == StringAlignment.Center)
    102         {
    103             stringStart.Y = bmpStr.Height / 2;
    104         }
    105         else if (alignment == StringAlignment.Far)
    106         {
    107             stringStart.Y = bmpStr.Height;
    108         }
    109 
    110         if (lineAlignment == StringAlignment.Near)
    111         {
    112             stringStart.X = bmpStr.Width;
    113         }
    114         else if (lineAlignment == StringAlignment.Center)
    115         {
    116             stringStart.X = bmpStr.Width / 2;
    117         }
    118         else if (lineAlignment == StringAlignment.Far)
    119         {
    120             stringStart.X = 0;
    121         }
    122     }
    123 }
    124 
    125 //……
    126 
    127 g.DrawString(str, font, new SolidBrush(Color.Red), stringStart, stringFormat);
    128 
    129 //……
    坐标计算

    五、示例程序源代码下载

    源工程文件:

     https://files.cnblogs.com/files/lesliexin/StringFormat.7z

  • 相关阅读:
    零拷贝报文捕获平台
    Table of Contents ---BCM
    bcm cmd
    Linux常用性能调优工具索引
    Vue params传值的坑
    安装了新的angular版本后无法运行老的angular版本项目
    后端返回的数据与前端console.log数据不一致问题
    门户页跳转页面 跳转指定的页面 接口会变成路由去显示 而不是显示组件
    配置git ssh 密钥
    grafana环境变量
  • 原文地址:https://www.cnblogs.com/lesliexin/p/12879270.html
Copyright © 2020-2023  润新知