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

如何在C#中更改richtextbox中多个大小的字体?,c#,winforms,richtextbox,rtf,C#,Winforms,Richtextbox,Rtf,我有一个richtextbox,我想让它像写字板一样工作。我的问题是,例如,如果我使用Calibri字体键入“123”,然后使用Arial字体键入“456”,并且我想更改2345的大小,它将不允许我这样做,因为它们有两种不同的字体类型。这就是我的问题所在: private void combo_sizes_TextChanged(object sender, EventArgs e) { if (rtb.SelectionFont == null) { rtb.S

我有一个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,因此在这种情况下,我可以从两个组合框中获取选定文本的大小和字体,但我希望在不丢失其原始字体的情况下更改大小。有解决办法吗


谢谢

将您的
所选文本
拆分为
字符
s。获取每个字符的字体,并更改其大小。

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

  • Font
    是任何输入之后都将使用的字体。所以,如果你想切换到另一种字体,这是你应该设置的
  • SelectionFont
    但是,它是当前所选内容的字体。这将随选择而改变,但也用于设置已输入部分文本的字体
但在一个时间和地点,两者中只能有一个。如果你想切换回标准字体,你需要在某处保留标准字体

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

还请注意:

  • 输入文本后的所有格式设置必须通过选择一个零件,然后更改该选择的属性:字体、颜色、样式来完成
  • 文本的任何部分以任何方式格式化后,您都不能直接在代码中更改文本,而只能使用AppendText、Copy、Cut、Past,否则您会弄乱格式
您的代码可能如下所示:

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。在没有选择的情况下,您可能遇到了问题


但是,我还是不确定你关于“拯救”前一个福恩的想法。想想写字板:它也不做任何类似的事情。将您使用的所有字体添加到字体列表中,甚至可能带有其他颜色,以及漂亮的名称,因为字体和样式听起来非常吸引人。

我在这里需要相同的字体。我没有找到最好的解决办法。。。所以,这是丑陋的一个

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;
    }
}
private void UglyChangeFontSize(RichTextBox rtb,float newSize=-1f,FontFamily=null){
如果(rtb.SelectionFont!=null){
如果(newSize<0)newSize=rtb.SelectionFont.Size;
如果(fontFamily==null)fontFamily=rtb.SelectionFont.fontFamily;
rtb.SelectionFont=新字体(fontFamily、newSize、rtb.SelectionFont.Style);
}
否则{
//备份选择
var sel=rtb.SelectionStart;
var selLen=rtb.SelectionLength;
//一个字符一个字符地改变
for(int k=0;k

改进版

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

  • 禁用RichTextBox图形(更改字体时)
  • 防止“逐字符修改”进入撤消/重做堆栈
  • 执行更改时显示等待光标
  • 要求

  • --我围绕这一点构建了我的代码,这是构建类似写字板的项目的良好开端
  • 代码

    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;
        }
    }
    
    RichTextBox myRichTextBox=new RichTextBox();
    RichOLE mRichOle=新的RichOLE(myRichTextBox);
    ...
    私有void UglyChangeFontSize(RichTextBox rtb,float newSize=-1f,FontFamily FontFamily=null){
    如果(rtb.SelectionFont!=null){
    如果(newSize<0)newSize=rtb.SelectionFont.Size;
    如果(fontFamily==null)fontFamily=rtb.SelectionFont.fontFamily;
    rtb.SelectionFont=新字体(fontFamily、newSize、rtb.SelectionFont.Style);
    }
    否则{
    Cursor=Cursors.WaitCursor;
    //对用户隐藏修改
    外部。锁窗和保持交叉位置(rtb,()=>
    {
    //备份选择
    var sel=rtb.SelectionStart;
    var selLen=rtb.SelectionLength;
    //禁用此“分段修改”的撤消[开始]
    rtb.SelectedRtf=rtb.SelectedRtf;//需要允许撤消
    //mFontLockEvents=true;//RicherTextBox
    mRichOle.EnableUndo(false);
    //禁用此“分段修改”的撤消[结束]
    //一个字符一个字符地改变
    for(int k=0;k
    我忘了说我是一名基础程序员,所以我根本不知道你的答案。请问,你能告诉我怎么做吗?没有人天生就是程序员。:)当你练习的时候,你会变得更像一个老师