c# - 如何在winform上绘制丰富格式的字符串?

标签 c# .net winforms drawstring richtext

我需要在 Windows 窗体上写一行丰富格式的文本。我怎样才能实现这个目标?

最佳答案

您必须将字符串拆分为具有相同格式的“ block ”,并绘制每个“ block ”。

使用 Graphics.MeasureString 计算位置,使用 Graphics.DrawString 进行最终绘制。

简单的示例代码(不解决自动换行、图像等问题...):

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();

        this.Paint += new PaintEventHandler(Form1_Paint);
        this.SizeChanged += new EventHandler(Form1_SizeChanged);
    }

    void Form1_SizeChanged(object sender, EventArgs e) {
        this.Invalidate();
    }

    public class RichText {
        public Font Font { get; set; }
        public Color? TextColor { get; set; }
        public string Text { get; set; }

        public RichText() { }
        public RichText(string text) {
            this.Text = text;
        }
        public RichText(string text, Font font) : this(text) {
            this.Font = font;
        }
        public RichText(string text, Color textColor) : this(text) {
            this.TextColor = textColor;
        }
        public RichText(string text, Color textColor, Font font) : this(text, textColor) {
            this.Font = font;
        }
    }
    void Form1_Paint(object sender, PaintEventArgs e) {
        var arial_8 = new Font("Arial", 8);
        var webdings_10 = new Font("Webdings", 10);

        var richTexts = new RichText[]{
            new RichText("Default text.")
            , new RichText("Default green text.", Color.Green)
            , new RichText("Regular arial 8.", arial_8)
            , new RichText("Bold arial 8.", new Font(arial_8, FontStyle.Bold))
            , new RichText("Regular webdings 10.", webdings_10)
            , new RichText("Regular blue webdings 10.", Color.Blue, webdings_10)
        };

        var g = e.Graphics;

        Point textPosition = new Point(0, 0);
        int maxWidth = this.ClientSize.Width;
        foreach (var richText in richTexts) {
            var text = richText.Text;
            if (string.IsNullOrEmpty(text)) { continue; }

            var font = richText.Font ?? Control.DefaultFont;
            var textColor = richText.TextColor ?? Control.DefaultForeColor;

            using (var brush = new SolidBrush(textColor)) {
                var rslt_Measure = g.MeasureString(text, font);
                if (rslt_Measure.Width + textPosition.X > maxWidth) {
                    // this code does not solve word-wraping
                    var rslt_Line = g.MeasureString("\r\n", font);
                    Point tmpTextPosition = new Point(0, textPosition.Y + (int)rslt_Line.Height);

                    g.DrawString(text, font, brush, tmpTextPosition);
                    var newPosition = tmpTextPosition;
                    newPosition.X += (int)rslt_Measure.Width;
                    textPosition = newPosition;
                }
                else {
                    g.DrawString(text, font, brush, textPosition);
                    var newPosition = textPosition;
                    newPosition.X += (int)rslt_Measure.Width;
                    textPosition = newPosition;
                }
            }
        }
    }
}

编辑:

如果您想要处理 RTF,也许此链接会很有用:

关于c# - 如何在winform上绘制丰富格式的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5390422/

相关文章:

c# - 如何使用 Thread.Sleep 为二叉树设置动画?

C# 动态加载/卸载 DLL Redux(当然使用 AppDomain)

c# - 索引超出范围错误;这里而不是那里?

c# - Form.Closing 未列为表单事件?

c# - errorprovider 在表单加载时看起来不同

c# - 验证文本框是否为空且输入了数字

c# - 如何在移动设备上的 Unity3d 中实现多点触控?

.net - 跟踪缓慢的托管 DLL 加载

.net - 有什么方法可以使 DataContractJsonSerializer 正确序列化字典吗?

.net - 如何保护用 C++ .NET 编写的应用程序