当前位置: 首页 > article >正文

C# GDI+的DrawString无法绘制Tab键的现象

【啰嗦2句】

     现在用C#的人很少了吧?GDI+更少了吧?所以这个问题估计也冷门。没关系,分享给特定需要的人也不错。

【问题现象】   

    工作中开发了一个报告编辑器,实现图文排版等功能,用着没什么问题,直到有一天发现,文本框粘贴的内容暗藏Tab键(保存为\t字符),比如“银丝鸡蛋面        GB 28050-2011       100克 ”,用DrawString怎么绘制都会忽略中间的间距,变成“银丝鸡蛋面GB 28050-2011100克”

   比较糟糕的是MySQL数据库查看时的值也是“银丝鸡蛋面GB 28050-2011100克”。

 【分析历程】

     刚开始并不知道是中间包含着Tab键,从MySQL数据库复制到NotePad++后,发现有这个tab分隔才找到原因。还以为是没法保存\t这个符号。

    既然有这个键值为什么DrawString没有识别并区分呢?不知道。CSDN的做法比较巧妙,我编辑这篇文章时,看到CSDN把Tab键转换成了8个空格。这个是不错的做法,按理说我的报告编辑器也可以这么做。但是,仍然希望所见所得吧,作为报告,希望保留内容的原始性。

    最终在微软在线文档中发现有个StringFormat.SetTabStops()方法,似乎是一个希望。链接看这个:微软文档StringFormat.SetTabStops(Single, Single[]) 方法

  【解决案例】

    1、微软文档的做法,其实并没有解决问题。

    新建一个窗体Form1,双击Paint事件编辑代码。

/// <summary>
/// 直接在Form的Paint演示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Paint(object sender, PaintEventArgs e)
{
    //注意“直接的”前面是换行符
    string text = "Hello, 移动中的鸭子!\n直接的\t方法\t来获\t取每\t个字符的精确位置。";
    Graphics graphics = e.Graphics;
    // 设置文本的布局,制表符将会根据这个对齐方式计算
    StringFormat format = new StringFormat();
    format.Alignment = StringAlignment.Near;
    //这个tabStops是重点,但是也很难搞懂
    float[] tabStops = { 100.0f,50.0f,20.0f,100.0f,20.0f };  //每个间隔跟上一个的间隔像素
    format.SetTabStops(0, tabStops);//设置起始符位置0,其他的按tabStops
    graphics.DrawString(text, this.Font, new SolidBrush(Color.Green), 10, 10, format);
}
原文:Hello, 移动中的鸭子!\n直接的\t方法\t来获\t取每\t个字符的精确位置

运行效果如下图:

这里微软官方解释:

tabStops 数组中的每个制表位偏移量(第一个除外)相对于上一个。 第一个制表位偏移量相对于由 firstTabOffset指定的初始偏移位置。 例如,如果初始偏移位置为 8,第一个制表位偏移量为 50,则第一个制表位位于位置 58。 如果初始偏移位置为零,则第一个制表位偏移量相对于位置 0(字符串原点)。

实际我测试了多个tabStops数组值,第一个值比较准,其他表现得莫名其妙。比如:

tabStops = { 100.0f,50.0f,20.0f,50.0f}

    由于资料很少,所以这个方案只能作为参考,可能受不同系统语言、地区等影响表现未必符合要求。有兴趣的读者可以再摸索摸索。

 2、参照CSDN这种做法,直接把\t替换为4个或8个空格。推荐用这种方法。

label3.Text = text.Replace("\t", "    ");

 


http://www.kler.cn/a/502489.html

相关文章:

  • 用python编写一个放烟花的小程序
  • Unity自带的真车模拟系统,速度不够大r时如何以匀速上桥
  • 工厂人员定位管理系统方案(二)人员精确定位系统架构设计,适用于工厂智能管理
  • VScode python 远程调试
  • Spring Boot中的依赖注入是如何工作
  • 基于改进粒子群优化的无人机最优能耗路径规划
  • 腾讯云AI代码助手编程挑战赛-智能聊天助手
  • 大语言模型预训练、微调、RLHF
  • YangQG 面试题汇总
  • Java安全—SPEL表达式XXESSTI模板注入JDBCMyBatis注入
  • 玩转大语言模型——langchain调用ollama视觉多模态语言模型
  • Ubuntu Server挂载AWS S3成一个本地文件夹
  • Nginx简述
  • MySQL表的增删改查(进阶)-上篇
  • Vue.js组件开发-图片剪裁性能优化最佳方案实例
  • 【JVM-2.3】深入解析JVisualVM:Java性能监控与调优利器
  • 【解决问题】WSL报错 Netlink send error : Invalid argument
  • 认识机器学习中的经验风险最小化准则
  • torch.einsum计算张量的外积
  • 每天五分钟深度学习框架pytorch:快速搭建VGG网络的基础模块VGG块
  • docker 日常使用(进入容器、查看日志)
  • [vue] $refs和$el的使用
  • Clojure语言的正则表达式
  • 代码随想录day24 | 贪心算法理论基础 leetcode 455.分发饼干 376.摆动序列 53. 最大子序和
  • 计算机网络 (40)域名系统DNS
  • django华为产品销售的数据爬虫与可视化分析