如何在C#中更改richtextbox中多种大小的字体?

Posted

技术标签:

【中文标题】如何在C#中更改richtextbox中多种大小的字体?【英文标题】:How to change the font of multiple sizes in richtextbox in C#? 【发布时间】:2021-09-09 13:25:07 【问题描述】:

我有一个丰富的文本框,我想让它像写字板一样工作。我的问题是,例如,如果我使用 Calibri 字体键入“123”,然后使用 Arial 字体键入“456”并且我想更改 2345 的大小,它不会让我这样做,因为他们有两个不同的字体类型。这就是我遇到的问题:

private void combo_sizes_TextChanged(object sender, EventArgs e)

    if (rtb.SelectionFont == null)
    
        rtb.SelectionFont = new Font(combo_fonts.Text, Convert.ToInt16(combo_sizes.Text));
    
    rtb.SelectionFont = new Font(rtb.SelectionFont.FontFamily, Convert.ToInt16(combo_sizes.Text));

我知道当 rtb 中的选定文本包含多种字体时,SelectionFont 等于 null,所以在这种情况下,我已经从两个组合框中获取选定文本的大小和字体,但我想更改大小在不丢失其原始字体的情况下。有解决办法吗?

谢谢

【问题讨论】:

【参考方案1】:

将您的selected text 拆分为chars。获取每个char 的字体,并更改其大小。

【讨论】:

我忘了说我是一个基础程序员,所以我根本没有得到你的答案。请问,你能告诉我怎么做吗? 没有人是天生的程序员。 :) 当你练习时,你会变得越来越有效率。我会尽可能简单地更新我的答案。【参考方案2】:

RichTextBox (RTB) 中有两种内置字体:

Font 是用于任何输入的那个。所以如果你想切换到另一种字体,这是你应该设置的 SelectionFont 然而是当前选择的字体。这将随着选择而改变,但它也用于设置已输入部分文本的字体。

但在同一时间和地点只能有其中之一。如果您想切换回标准 Front,您需要在某处保留标准字体。

或者您可以将您使用的所有字体存储在一个列表中,然后您可以在组合框中提供它们。

另请注意:

输入文本后的所有格式必须选择一个部分,然后更改该选择的属性:字体、颜色、样式.. 以任何方式对文本的任何部分进行格式化后,您不得直接在代码中更改文本,而只能使用 AppendText、复制、剪切、粘贴,否则您会弄乱格式!李>

您的代码可能会这样工作:

public Form1()

    InitializeComponent();

    lastSelectionFont = rtb.SelectionFont;
    lastFont = rtb.Font;
    //..



Font lastSelectionFont;
Font lastFont;
private void richTextBox1_TextChanged(object sender, EventArgs e)


    if (rtb.SelectionLength > 0)
    
        lastSelectionFont = rtb.SelectionFont;
        rtb.SelectionFont = new Font(rtb.SelectionFont.FontFamily, 
                                Convert.ToInt16(combo_sizes.Text));
    
    else
    
        lastFont = rtb.Font;
        rtb.Font = new Font(rtb.Font.FontFamily, 
                               Convert.ToInt16(combo_sizes.Text));
    

请注意,SelectionFont 不会为 null,除非您将其设置为 null。当没有选择时,您可能遇到了问题..

但同样,我不确定您对“拯救”以前的 Forn 的想法。想想 wordPad:它也不会那样想。将您使用的所有字体添加到字体列表中,甚至可以使用它们的颜色,以及像字体和样式这样漂亮的名称听起来非常有吸引力。

【讨论】:

您好,感谢您的帮助。我在创建 lastSelectionFont 和 lastFont 时遇到问题,我收到此错误:“字段初始值设定项无法引用非静态字段、方法或属性” 是的,我的错 - 只有在编译时可计算的表达式才能像我一样被分配。抱歉,我已更改代码并将初始化移至表单的构造函数.. 为什么要新建一个ComboBox? 哎哟!我的另一个小错误。我已经使用这两行来保存自己在我的测试程序中重命名控件.. 我已经删除了它们,再次抱歉;-)【参考方案3】:

我在这里也需要同样的东西。而且我没有找到最好的解决方案......所以,这是丑陋的一个。

private void UglyChangeFontSize(RichTextBox rtb, float newSize = -1f, FontFamily fontFamily = null) 
    if (rtb.SelectionFont != null) 

        if (newSize < 0) newSize = rtb.SelectionFont.Size;
        if (fontFamily == null) fontFamily = rtb.SelectionFont.FontFamily;

        rtb.SelectionFont = new Font(fontFamily, newSize, rtb.SelectionFont.Style);
    
    else 
        // Backup Selection
        var sel = rtb.SelectionStart;
        var selLen = rtb.SelectionLength;

        // Change, char by char
        for (int k = 0; k < selLen; k++) 
            rtb.Select(sel + k, 1);

            if (newSize < 0) newSize = rtb.SelectionFont.Size;
            var ff = fontFamily ?? rtb.SelectionFont.FontFamily;

            rtb.SelectionFont = new Font(fontFamily, newSize, rtb.SelectionFont.Style);
        

        // Restore Selection
        rtb.SelectionStart = sel;
        rtb.SelectionLength = selLen;
    


改进版

这是一个更好的版本,它包括:

    禁用 RichTextBox 绘图(更改字体时); 防止“逐字符修改”进入撤消/重做堆栈; 执行更改时显示 WaitCursor。

要求

    External.cs RichOLE.cs (Optional) RicherTextBox -- 我围绕这个构建了我的代码,这是构建一个类似写字板的项目的一个很好的开始

代码

RichTextBox myRichTextBox = new RichTextBox();
RichOLE mRichOle = new RichOLE(myRichTextBox);

...

private void UglyChangeFontSize(RichTextBox rtb, float newSize = -1f, FontFamily fontFamily = null) 
    if (rtb.SelectionFont != null) 

        if (newSize < 0) newSize = rtb.SelectionFont.Size;
        if (fontFamily == null) fontFamily = rtb.SelectionFont.FontFamily;

        rtb.SelectionFont = new Font(fontFamily, newSize, rtb.SelectionFont.Style);
    
    else 
        Cursor = Cursors.WaitCursor;

        // Hide the modifications from the user
        External.LockWindowAndKeepScrollPosition(rtb, () => 
        
            // Backup Selection
            var sel = rtb.SelectionStart;
            var selLen = rtb.SelectionLength;

            // Disable UNDO for this "in pieces modifications" [START]
            rtb.SelectedRtf = rtb.SelectedRtf; // Required to allow Undo
            //mFontLockEvents = true; // RicherTextBox
            mRichOle.EnableUndo(false);
            // Disable UNDO for this "in pieces modifications" [END]

            // Change, char by char
            for (int k = 0; k < selLen; k++) 
                rtb.Select(sel + k, 1);

                // again, ugly... buuut we have Branch Prediction (google it)
                if (newSize < 0) newSize = rtb.SelectionFont.Size;
                var ff = fontFamily ?? rtb.SelectionFont.FontFamily;

                rtb.SelectionFont = new Font(fontFamily, newSize, rtb.SelectionFont.Style);
            

            // Disable UNDO for this "in pieces modifications" [START]
            //mFontLockEvents = false; // RicherTextBox
            mRichOle.EnableUndo(true);
            // Disable UNDO for this "in pieces modifications" [END]

            // Restore Selection
            rtb.SelectionStart = sel;
            rtb.SelectionLength = selLen;
        );
        Cursor = Cursors.Default;
    

【讨论】:

以上是关于如何在C#中更改richtextbox中多种大小的字体?的主要内容,如果未能解决你的问题,请参考以下文章

如何更改RichTextBox高度以适应C#中的新字体大小

如何在 RichTextBox 中添加 RTF 文本,Win C#

如何在 RichTextBox C# 中“对齐”文本?

如何读取或者打印C#中RichTextBox中的文本内容?

C#中,如何让richTextBox旁边的滚动条始终处于最下方

c#中如何设置richtextbox 字体颜色