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

问题描述 投票:3回答:3

我有一个richtextbox,我想让它像写字板一样工作。我的问题是,例如,如果我使用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,所以在这种情况下我已经使它从两个组合框中获取所选文本的大小和字体,但我想改变大小而不会失去它原始字体。有解决方案吗?

谢谢

c# winforms richtextbox rtf
3个回答
0
投票

打破你的selected textchars。获取每个char的字体,并更改其大小。


0
投票

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

  • Font是任何输入之后将使用的那个。因此,如果您想切换到另一种字体,这就是您应该设置的内容
  • 然而,SelectionFont是当前选择的字体。这将随选择而改变,但它也用于设置已输入文本的部分字体。

但是,在任何时间和地点都只能有一个。如果要切换回标准Front,则需要在某处保留标准Font。

或者您可以在List中存储您使用的所有字体,并且可以在comboBox中提供它们。

还请注意:

  • 输入文本后的所有格式都必须选择一个部件,然后更改该选择的属性:字体,颜色,样式..
  • 在以任何方式格式化文本的任何部分后,您不能直接在代码中更改文本,而只使用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 ubnless,您将其设置为null。没有选择时你可能会遇到问题。

但同样,我不确定你的“拯救”前任福恩的想法。想想wordPad:它也没有做任何想法。将您使用的所有字体添加到字体列表中,甚至可以使用theris颜色,并且字体和样式的好名称听起来非常有吸引力。


0
投票

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

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;
    }
}

改良版

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

  1. 禁用RichTextBox绘图(更改字体时);
  2. 防止“char-by-char修改”转到Undo / Redo堆栈;
  3. 执行更改时显示WaitCursor。

要求

  1. External.cs
  2. RichOLE.cs
  3. (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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.