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

时间:2014-11-02 13:59:12

标签: c# winforms richtextbox rtf

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

由于

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

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

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

请注意:

  • 输入文字后的所有格式必须选择一个零件,然后更改该选项的属性:字体,颜色,样式..
  • 在以任何方式格式化文本的任何部分后,您不能直接在代码中更改文本,而只使用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颜色,并且字体和样式的漂亮名称听起来非常有吸引力。

答案 2 :(得分: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. 防止“按字符修改”进入撤消/重做堆栈;
  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;
    }
}