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,其他的按tabStopsgraphics.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", " ");

相关文章:
C# GDI+的DrawString无法绘制Tab键的现象
【啰嗦2句】 现在用C#的人很少了吧?GDI更少了吧?所以这个问题估计也冷门。没关系,分享给特定需要的人也不错。 【问题现象】 工作中开发了一个报告编辑器,实现图文排版等功能,用着没什么问题,直到有一天…...
C# GID+绘制不透明和半透明的线条
绘制线条时,必须将 Pen 对象传递给 DrawLine 类的 Graphics 方法。 Pen 构造函数的参数之一是 Color 对象。 若要绘制不透明的线条,请将颜色的 alpha 分量设置为 255。 若要绘制半透明的线条,请将 alpha 分量设置为从 1 到 254 的任何值。 在…...
L4-Prompt-Delta
Paper List PromptPapers:https://github.com/thunlp/PromptPapersDeltaPapers: https://github.com/thunlp/DeltaPapers Programming Toolkit OpemPrompt: https://github.com/thunlp/OpenPromptOpenDelta: https://github.com/thunlp/OpenDelta 一、传统微调方法࿱…...
Qt 自定义控件(Qt绘图)
一、QPaintEvent绘图事件1、QPaintEvent是Qt框架中一个重要的事件类,专门用于处理绘图事件。 2、当Qt视图组件需要重绘自己的一部分时,就会产生QPaintEvent事件。 3、Qt视图组件重绘自己,通常发生在以下情况: (1)、窗口第一次显示时: 当窗…...
electron 上怎么用node 调用 c++ 提供的方法
背景 在 Electron 上调用 C 代码的场景主要出现在需要执行高性能、低延迟的任务,或者需要与现有的本地 C 库集成时。这些场景往往涉及底层系统交互、性能优化或跨平台兼容性需求。 我们都知道c 的性能和安全性都比JavaScript 要高,但我认为在 Electron …...
Chromium 132 编译指南 Windows 篇 - Git 初始化设置 (四)
1. 引言 在 Chromium 编译指南系列的前几篇文章中,我们已经完成了编译环境的基础设置和关键环境变量的配置。本篇将重点介绍 Git 的安装与初始化配置,这是获取和管理 Chromium 源代码的重要前提。 2. 安装 Git 在 Windows 环境下,Git 并不…...
day03-前端Web-Vue3.0基础
目录 前言1. Vue概述2. 快速入门2.1 需求2.2 步骤2.3 实现 3. Vue指令3.1 介绍3.2 v-for3.2.1 介绍3.2.2 演示3.2.3 v-for的key3.2.4 案例-列表渲染 3.3 v-bind3.3.1 介绍3.3.2 演示3.3.3 案例-图片展示 3.4 v-if & v-show3.4.1 介绍3.4.2 案例-性别职位展示 3.6 v-model3.…...
Windows 下Mamba2 / Vim / Vmamba 环境安装问题记录及解决方法终极版(无需绕过triton)
导航 安装教程导航 Mamba 及 Vim 安装问题参看本人博客:Mamba 环境安装踩坑问题汇总及解决方法(初版)Linux 下Mamba 及 Vim 安装问题参看本人博客:Mamba 环境安装踩坑问题汇总及解决方法(重置版)Windows …...
GitLab本地服务器配置ssh和克隆项目
1. 本地安装好git git链接:https://git-scm.com/downloads/win 无脑点击下一步安装即可,打开Git Bash命令终端如下: 2. 配置本地用户名和邮箱 git config --global user.name "你的名字" git config --global user.email "你的邮箱&quo…...
Win10和11 git/Android Studio遇到filename too long问题的解决
1、打开windows长文件、长路径支持: 可以参考这篇文章: 修改注册表方法: 使用Admin登陆machine,在run中输入regedit并回车; 找到路径 ’Computer -> HKEY_LOCAL_MACHINE -> SYSTEM -> CurrentControlSet -&g…...
【JavaWeb学习Day11】
java程序操作数据库(JDBC) JDBC:(Java DataBase Connectivity),就是使用Java语言操作关系型数据库的一套API。 本质: 1.sun公司官方定义的一套操作所有关系型数据库的规范、即接口。 2.各个数据库厂商去…...
rom定制系列------小米max3安卓12 miui14批量线刷 默认开启usb功能选项 插电自启等
小米Max3是小米公司于2018年7月19日发布的机型。此机型后在没有max新型号。采用全金属一体机身设计,配备6.9英寸全面屏.八核处理器骁龙636,后置双摄像头1200万500万像素,前置800万像素.机型代码 :nitrogen.官方最终版为稳定版12.5…...
CES 2025|美格智能高算力AI模组助力“通天晓”人形机器人震撼发布
当地时间1月7日,2025年国际消费电子展(CES 2025)在美国拉斯维加斯正式开幕。美格智能合作伙伴阿加犀联合高通在展会上面向全球重磅发布人形机器人原型机——通天晓(Ultra Magnus)。该人形机器人内置美格智能基于高通QC…...
汽车电子相关的协议UDS、DOIP、CAN
UDS协议 UDS(Unified Diagnostic Services,统一诊断服务协议) 是一种标准化的通信协议,广泛应用于汽车电子系统中,尤其是在车辆诊断和服务过程中。它用于车辆的诊断、维护、控制和测试,支持通过车载诊断接…...
k8s笔记29--使用kyverno提高运维效率
k8s笔记29--使用kyverno提高运维效率 介绍原理安装应用场景自动修正测试环境pod资源强制 Pod 标签限制容器镜像来源禁止特权容器其它潜在场景 注意事项说明 介绍 Kyverno是一个云原生的策略引擎,它最初是为k8s构建的,现在也可以在k8s集群之外用作统一的…...
Life Long Learning(李宏毅)机器学习 2023 Spring HW14 (Boss Baseline)
1. 终身学习简介 神经网络的典型应用场景是,我们有一个固定的数据集,在其上训练并获得模型参数,然后将模型应用于特定任务而无需进一步更改模型参数。 然而,在许多实际工程应用中,常见的情况是系统可以不断地获取新数据,例如 Web 应用程序中的新用户数据或自动驾驶中的…...
libc.so.6不兼容
1、查看电脑所有libc.so.6 daviddavid-Shangqi-X4270:~/MySoft/ubuntusoft$ locate libc.so.6 /home/david/MySoft/ubuntusoft/EXEApp/libc.so.6 /home/david/MySoft/ubuntusoft/EXEApp_TEST/libc.so.6 /home/david/MySoft/ubuntusoft/RTMG_APP/libc.so.6 /home/david/MySoft/…...
树的模拟实现
一.链式前向星 所谓链式前向星,就是用链表的方式实现树。其中的链表是用数组模拟实现的链表。 首先我们需要创建一个足够大的数组h,作为所有结点的哨兵位。创建两个足够大的数组e和ne,一个作为数据域,一个作为指针域。创建一个变…...
AsyncOperation.allowSceneActivation导致异步加载卡死
先看这段代码,有个诡异的问题,不确定是不是bug public class Test : MonoBehaviour {void Start(){StartCoroutine(LoadScene(Ego.LoadingLevel));}IEnumerator LoadScene(string sceneName){LoadingUI.UpdateProgress(0.9f);yield return new WaitForS…...
如何搭建 Vue.js 开源项目的 CI/CD 流水线
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

