如何使用面板上的图形类绘制多色文本?

2023-12-04

我想在面板上绘制以下文本:

sample text

这是一个多颜色的文本。

我找到了这个article关于绘制彩色文本。

我用单词替换了字符,但它不起作用。

output-screenshot

(我使用FillPath/DrawPath来绘制文本)

my code:

private void Form1_Paint(object sender, PaintEventArgs e)
    {
        const string txt = "C# Helper! Draw some text with each letter in a random color.";

        // Make the font.
        using (Font the_font = new Font("Times New Roman", 40,
            FontStyle.Bold | FontStyle.Italic))
        {
            // Make a StringFormat object to use for text layout.
            using (StringFormat string_format = new StringFormat())
            {
                // Center the text.
                string_format.Alignment = StringAlignment.Center;
                string_format.LineAlignment = StringAlignment.Center;
                string_format.FormatFlags = StringFormatFlags.NoClip;

                // Make CharacterRanges to indicate which
                // ranges we want to measure.

                MatchCollection mc = Regex.Matches(txt, @"[^\s]+");
                CharacterRange[] ranges = new CharacterRange[mc.Count];
                int g = 0;
                foreach (Match m in mc)
                {
                    ranges[g] = new CharacterRange(m.Index, m.Length);
                    g++;
                }
                string_format.SetMeasurableCharacterRanges(ranges);

                // Measure the text to see where each character range goes.
                Region[] regions =
                    e.Graphics.MeasureCharacterRanges(
                        txt, the_font, this.ClientRectangle,
                        string_format);

                // Draw the characters one at a time.
                for (int i = 0; i < ranges.Length; i++)
                {
                    // See where this character would be drawn.
                    RectangleF rectf = regions[i].GetBounds(e.Graphics);
                    Rectangle rect = new Rectangle(
                        (int)rectf.X, (int)rectf.Y,
                        (int)rectf.Width, (int)rectf.Height);

                    // Make a brush with a random color.
                    using (Brush the_brush = new SolidBrush(RandomColor()))
                    {
                        // Draw the character.
                        string txts = txt.Substring(ranges[i].First, ranges[i].Length);
                        e.Graphics.DrawString(txts,
                            the_font, the_brush, rectf, string_format);
                    }
                }
            }
        }
    }

问题是什么?


这(在某种程度上)是经典。
执行的相当精确的测量之间存在差异测量字符范围和实际执行的字符串绘制Graphics.DrawString.

The RectagleF由返回Region.GetBounds()按原样考虑文本的大小。
Graphics.DrawString另一方面,在计算给定边界内的文本配置时执行某种网格拟合。

我不会在这里解释它,这是一个相当广泛的问题,但我已经写过一些相关内容:
在位图上绘制长字符串会导致绘图问题.
如果你有兴趣,你可以找到一些详细信息Graphics在此上下文中的对象行为。

总而言之,文本测量正确,但调整Graphics.DrawString执行,导致文本不完全适合测量的边界:绘制的文本稍微溢出.

你可以纠正这个problem使用几个StringFormat flags:
Add [StringFormat].Trimming = StringTrimming.None

应用此设置后,您可以立即看到问题所在:最后一个字符(或几个字符)被换行到新行,弄乱了绘图。

要更正它,请添加StringFormatFlags.NoWrap to StringFormatFlags.NoClip
显然,这将解决问题。显然是因为现在整个字符串都绘制在一条线上。

我向你建议另一种方法,使用文本渲染器.DrawText渲染字符串。
注意TextRenderer实际上是使用的类WinForms控件(好吧,不是全部)将文本渲染到屏幕上。

这是使用以下方法的结果:

MeasureCharacterRanges

示例代码,使用原始代码并进行一些修改:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    Control control = sender as Control;
    const string txt = "C# Helper! Draw some text with each word in a random color.";

    TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter |
                            TextFormatFlags.NoPadding | TextFormatFlags.NoClipping;

    using (StringFormat format = new StringFormat())
    {
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;

        MatchCollection mc = Regex.Matches(txt, @"[^\s]+");
        CharacterRange[] ranges = mc.Cast<Match>().Select(m => new CharacterRange(m.Index, m.Length)).ToArray();
        format.SetMeasurableCharacterRanges(ranges);

        using (Font font = new Font("Times New Roman", 40, FontStyle.Regular, GraphicsUnit.Point))
        {
            Region[] regions = e.Graphics.MeasureCharacterRanges(txt, font, control.ClientRectangle, format);

            for (int i = 0; i < ranges.Length; i++)
            {
                Rectangle WordBounds = Rectangle.Round(regions[i].GetBounds(e.Graphics));
                string word = txt.Substring(ranges[i].First, ranges[i].Length);

                TextRenderer.DrawText(e.Graphics, word, font, WordBounds, RandomColor(), flags);
            }
        }
    }
}


private Random rand = new Random();
private Color[] colors =
{
    Color.Red,
    Color.Green,
    Color.Blue,
    Color.Lime,
    Color.Orange,
    Color.Fuchsia,
};

private Color RandomColor()
{
    return colors[rand.Next(0, colors.Length)];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用面板上的图形类绘制多色文本? 的相关文章

  • 在 C# 中从另一个子窗体调用一个子窗体

    我有3种表格 FormS FormS和FormS 其中FormAT是mdiParent表格 表格B和C是子表格 我在 FormA 加载事件中编写以下代码 private void frmMain Load object sender Eve
  • 从标签 ID 更改整个 gridview 单元格颜色

    试图弄清楚当我有标签 ID 时如何更改 gridview 单元格的背景颜色
  • .NET Core == .NET Framework 5 吗?

    我一直在寻找书籍来研究最新的 NET Framework 据我所知 NET 最高为 4 6 但 ASP NET 最高为 5 核心 NET Core 是 NET 5 的名称还是我们目前仍使用 NET 4 6 去引用斯科特 汉塞尔曼 http
  • .NET 远程处理回调

    是否可以通过远程处理传输回调 我想做一些类似的事情myRemoteObject PerformStuff x gt Console WriteLine x 如果没有 我将如何实现等效的功能 Edit 我知道 Remoting 已被 WCF
  • 将组合框添加到 DataGridView 标头

    当我运行代码时 dataGridView TopLeftHeaderCell 也有一个组合框 我怎样才能改变这一点 这是我的代码 public void AddHeaders DataGridView dataGridView for in
  • idleTimeout 和 ShutdownTimeout 之间的区别

    我正在尝试放宽网站的会话过期策略 以便用户可以指定会话超时间隔 我需要弄清楚应该指定哪些网站相关设置 以免过多限制用户 例如 可能需要 1 天的间隔 我将使用门票来实现这一点 现在 我知道我可以在网站的 web config 文件中指定id
  • StringComparison.InvariantCultureIgnoreCase 去哪儿了?

    我正在将 C 代码移植到 Windows 应用商店应用程序 令我惊讶的是 以下代码不再起作用 someString Equals someOtherString StringComparison InvariantCultureIgnore
  • 如何让 C# 设计器编辑我的结构属性?

    我正在使用 C 创建一个具有多个自定义属性的自定义 Windows 窗体控件 这些属性之一是一个带有几个整数字段的简单结构 public struct Test public int A B Test Test Category MyCat
  • 如何在输入错误的情况下回滚 gridview 中的更改

    我有一个绑定到对象列表的 DataGridView 它有一些用户可以编辑的列 某些输入对于整个行来说是不允许的 如果用户在某些单元格中输入无效输入 我该如何回滚 我尝试使用 RowValidating 事件处理程序 但在更改单元格值后未调用
  • 如何使用 DateTime 计算已经过去了多少时间?

    我有一个启动操作的按钮单击事件 private void Diagnose Click object sender EventArgs e processfinish false timer2 Enabled true timerCount
  • 如何从子窗体访问winforms父窗体控件

    在 Form1 中 我有一个 DataGridView 和多个文本框 当我单击 Form2 中的 A 按钮时 我需要将 DataGridView 和多个文本框中的数据保存到数据库中 如何在C Sharp Windows应用程序中实现 For
  • 从另一个 FORM 中取回隐藏的 FORM

    我有两种形式Form1 and Form2 我正在打开Form2 from Form1 on button Click Form2 obj2 new Form2 this Visible false obj2 Show 然后我想回来Form
  • C# 和月历,选择多个日期

    我正在制作一个程序 可以帮助人们用 C 为某个部门 预订 订单 他们需要能够选择不同月份的多个日期 我更愿意拥有它 这样他们就可以单击一个日期 然后按住 Shift 键单击另一个日期以选择这两个日期之间的所有日期 并控制单击以进行单选 取消
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • C# Winforms Designer 无法打开,因为它无法在同一程序集中找到类型

    我收到以下错误 找不到类型 My Special UserControl 请确保引用包含此类型的程序集 如果此类型是您的开发项目的一部分 请确保已使用当前平台或任何 CPU 的设置成功构建该项目 但没有任何意义的是My Special Us
  • 我需要安装什么才能获取 Microsoft.TeamFoundation.WorkItemTracking.Client.dll?

    我只需要安装VS2010 SDK http www microsoft com downloads en details aspx FamilyID 47305cf4 2bea 43c0 91cd 1b853602dcc5 是否有 TFS2
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • 绘制多边形

    我正在使用 Google Maps API V3 根据路径绘制多边形 该路径是随机未排序坐标点 LatLng 的数组 这会产生以下形状 Polylines intersect Problem 由于多边形的形状取决于路径中点的顺序 因此如何对
  • 对多个对象使用事件处理程序

    我有 20 件物品List
  • IDisposable 的显式实现

    虽然有很多关于IDisposable在 SO 上找到 我还没有找到答案 我通常遵循这样的做法 当我的一个班级拥有一个IDisposable对象然后它也实现IDisposable并打电话Dispose在拥有的对象上 然而最近我遇到了一个类 它

随机推荐

  • 使用 VSTS 任务创建 AD 应用程序

    我正在尝试创建一个 VSTS 任务 它应该创建一个 AD 应用程序 以 DeployAzureResouceGroup 作为示例 我创建了以下脚本 CmdletBinding param Trace VstsEnteringInvocati
  • 返回局部变量的地址与返回指向局部变量的指针

    我的testing cpp中有这个 class Supp public virtual Supp add Supp val 0 class SubA public Supp public int val SubA int a val a i
  • jooq 多重集通过多重集上的条件对结果集进行排序

    收集 mit jooq 的多重集的第一次经验 我尝试弄清楚如何根据多重集的某些标准对结果集进行排序 考虑带有产品表的数据结构 每个产品都可以分配任意数量的存储空间 使用此查询获取产品时 List
  • Apache Solr 快速入门教程 - 加载主类 SimplePostTool 时出错

    我正在关注Apache Solr 快速入门教程 本教程遇到了对丰富文件的目录进行索引的情况 这需要实现java Dauto Drecursive org apache solr util SimplePostTool docs 我收到一条错
  • 重置主屏幕的导航堆栈(React Navigation 和 React Native)

    我的导航有问题反应导航和反应本机 这是关于重置导航并返回主屏幕 我已经在 DrawerNavigator 内部构建了 StackNavigator 并且主屏幕和其他屏幕之间的导航正在工作 但问题是 导航堆栈不断增长 我不知道如何从堆栈中删除
  • ScheduledActionService.Find 抛出 ArgumentException

    我在市场中部署了一个 Windows Phone 7 应用程序 该应用程序通过周期性任务后台代理更新其动态磁贴 一位用户报告了磁贴在工作一段时间后不再更新的问题 当他们检查手机上的后台任务时 它被禁用 并且 下次打开该应用程序时重新打开后台
  • Prolog:比较列表列表中的列表

    我现在很长时间试图找出我的错误是什么 但我无法做到 任务 我们必须弄清楚如何找到包含列表列表形式的 9 个元素的列表的三种排列 每个列表列表应包含三个子列表 每个子列表包含三个元素 但不允许任何元素与两个不同子列表中的另一个元素在一起 对于
  • Rust 中如何检查函数是否被调用?

    我有一个功能如下 pub fn registration student id T StudentId registrar T RegistrarID More code here if num of students lt student
  • d3-force 初始化图后更新forceCollide的半径

    这个问题是上一个题为 初始化图后强制更新参数 的问题的后续问题 D3 初始化图后强制更新参数 并且 altocumulus 回答了 我试图在修改某些节点的半径后更新模拟力 然而 当我呼吁forceCollide来解释它不起作用的变化 该图首
  • 使用反射修改字符串的目的是什么?

    我正在读一本article这就是说 Java 字符串并不是完全不可变的 但是 在本文修改字符串的示例代码中 它调用了 string toUpperCase toCharArray 这会返回一个新字符串 那么 如果您无论如何调用 toUppe
  • 向 sys.excepthook 添加函数

    假设我有这样的东西 它会向logging critical import sys def register handler orig excepthook sys excepthook def error catcher exc info
  • 如何在 64 位 Windows 上安装 SciPy?

    如何在我的系统上安装 SciPy 对于 NumPy 部分 SciPy 所依赖的 实际上有一个适用于 64 位 Windows 的安装程序 numpy 1 3 0 win amd64 py2 6 msi 是直接下载URL 2310144字节
  • Java - 通过 Java 套接字广播语音

    我创建了一个从客户端接收声音的服务器应用程序 然后广播该声音 该声音以字节形式存储 并将字节发送回连接到服务器的客户端 现在我只使用一个客户端进行测试 该客户端正在接收回语音 但声音一直断断续续 有人可以告诉我我做错了什么吗 我想我理解声音
  • Python 2 中的扩展元组解包

    是否可以在 Python 2 中模拟扩展元组拆包 具体来说 我有一个 for 循环 for a b c in mylist 当 mylist 是大小为 3 的元组列表时 它可以正常工作 如果我传入大小为 4 的列表 我希望相同的 for 循
  • Angular 2 变更检测 - 如何解决组件之间的循环依赖关系?

    我读到 Angular 2 变更检测是单向的 从组件树的顶部到底部 并且在一次通过后变得稳定 这意味着没有多个变更检测周期 考虑到这些假设 如果我们的父组件和子组件具有相互依赖的属性 会发生什么情况 例子 根据用户事件 父组件更新子组件属性
  • 卷曲 cookie 处理

    是否有可能使用 cURL 时 并非每个用户都使用相同的 cookie 因为我存储得到的 cookie 很酷 但是这个 cookie 会被每个人使用 而且应该如此 因为它是一个登录 cookie Charlie 这是 cookie 工作原理的
  • 语法错误:当前未启用对实验性语法“jsx”的支持

    我无法使用我创建的 npm 组件包 我已经成功发布了该包 但是当我在新代码中使用它时 它显示此错误 SyntaxError home trinendra Desktop react test node modules iconbox1 in
  • SSIS:创建具有不同行格式的平面文件

    我想创建一个平面文件输出 其中行的格式不同 文件有标题行 中间数据行 页脚行 文件如下所示 H deptcode123 deptNameXYZ totalemp300 E Sam Johnson address1 empCode1 many
  • window.open() 中的 name 参数是什么

    请有人告诉我这个窗口的名称是什么window open 是标题名称还是java脚本语言中的某个ID windowName 为新窗口指定的名称 该名称可用于再次引用该窗口 打开窗口后 您会想用它做各种各样的事情 例如移动它然后你就可以做
  • 如何使用面板上的图形类绘制多色文本?

    我想在面板上绘制以下文本 这是一个多颜色的文本 我找到了这个article关于绘制彩色文本 我用单词替换了字符 但它不起作用 我使用FillPath DrawPath来绘制文本 my code private void Form1 Pain