How to change FontStyle back in RichTextBox?

I'm using a click button event to make selection text bold, it works. But I want to make it regular when I select it and click the same button again but It doesn't work.

private void btnBold_Click(object sender, EventArgs e)
        {
            if (rtbMakale.SelectionLength > 0)
            {
                if (isItBold())
                {
                    rtbMakale.SelectionFont = new Font(rtbMakale.SelectionFont,
                        FontStyle.Regular | rtbMakale.SelectionFont.Style);
                    rtbMakale.SelectionLength = 0;
                }
                else
                {
                    rtbMakale.SelectionFont = new Font(rtbMakale.SelectionFont,
                        FontStyle.Bold | rtbMakale.SelectionFont.Style);
                    rtbMakale.SelectionLength = 0;
                }

            }

            bool isItBold()
            {
                if (rtbMakale.SelectionFont.Bold)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

2 answers

  • answered 2020-03-31 09:04 D J

    I have edited the code and it is fully functional. Using this, you can also perform many other formatting operations easily. Below, I have also added the link from where I derived this.

    private void button1_Click(object sender, EventArgs e)
        {
    
            if (_richTextBox1.SelectionLength > 0)
            {
                if (_richTextBox1.SelectionFont.Bold == false)
                {
                    ChangeOrSetFont(_richTextBox1.SelectionFont.ToString(), _richTextBox1.SelectionFont.Size, FontStyle.Bold, true);
                }
                else
                {
                    ChangeOrSetFont(_richTextBox1.SelectionFont.ToString(), _richTextBox1.SelectionFont.Size, FontStyle.Regular, true);
                }
            }
        }
    
        bool _maskChanges;
    
        private void ChangeFontStyleForSelectedText(string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            _maskChanges = true;
            try
            {
                int txtStartPosition = _richTextBox1.SelectionStart;
                int selectionLength = _richTextBox1.SelectionLength;
                if (selectionLength > 0)
                    using (RichTextBox txtTemp = new RichTextBox())
                    {
                        txtTemp.Rtf = _richTextBox1.SelectedRtf;
                        for (int i = 0; i < selectionLength; ++i)
                        {
                            txtTemp.Select(i, 1);
                            txtTemp.SelectionFont = RenderFont(txtTemp.SelectionFont, familyName, emSize, fontStyle, enableFontStyle);
                        }
    
                        txtTemp.Select(0, selectionLength);
                        _richTextBox1.SelectedRtf = txtTemp.SelectedRtf;
                        _richTextBox1.Select(txtStartPosition, selectionLength);
                    }
            }
            finally
            {
                _maskChanges = false;
            }
        }
    
        private Font RenderFont(Font originalFont, string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            if (fontStyle.HasValue && fontStyle != FontStyle.Regular && fontStyle != FontStyle.Bold && fontStyle != FontStyle.Italic && fontStyle != FontStyle.Underline)
                throw new System.InvalidProgramException("Invalid style parameter to ChangeFontStyleForSelectedText");
    
            Font newFont;
            FontStyle? newStyle = null;
            if (fontStyle.HasValue)
            {
                if (fontStyle.HasValue && fontStyle == FontStyle.Regular)
                    newStyle = fontStyle.Value;
                else if (originalFont != null && enableFontStyle.HasValue && enableFontStyle.Value)
                    newStyle = originalFont.Style | fontStyle.Value;
                else
                    newStyle = originalFont.Style & ~fontStyle.Value;
            }
    
            newFont = new Font(!string.IsNullOrEmpty(familyName) ? familyName : originalFont.FontFamily.Name,
                                emSize.HasValue ? emSize.Value : originalFont.Size,
                                newStyle.HasValue ? newStyle.Value : originalFont.Style);
            return newFont;
        }
    
        private void ChangeOrSetFont(string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            if (_richTextBox1.SelectionType == RichTextBoxSelectionTypes.Empty)
            {
                SetSelectionFont(familyName, emSize, fontStyle, enableFontStyle);
            }
            else
            {
                ChangeFontStyleForSelectedText(familyName, emSize, fontStyle, enableFontStyle);
            }
        }
    
        private void SetSelectionFont(string familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle)
        {
            Font renderedFont = RenderFont(_richTextBox1.SelectionFont, familyName, emSize, fontStyle, enableFontStyle);
            _richTextBox1.SelectionFont = renderedFont;
        }
    

    Here is the link:

    http://how-to-code-net.blogspot.com/2014/01/how-to-make-custom-richtextbox-control.html

  • answered 2020-03-31 09:29 NineBerry

    The problem is here:

    rtbMakale.SelectionFont = new Font(rtbMakale.SelectionFont,
                    FontStyle.Regular | rtbMakale.SelectionFont.Style);
    

    In this case, SelectionFont.Style contains the flag FontStyle.Bold. By using the OR operator on the old style, all the existing styles, including bold, are retained.

    Instead, use logical operators to remove the bold flag from the style:

    rtbMakale.SelectionFont = new Font(rtbMakale.SelectionFont,
        rtbMakale.SelectionFont.Style & ~FontStyle.Bold);
    

    Read this part rtbMakale.SelectionFont.Style & ~FontStyle.Bold as bitwise operation "Current Style AND NOT bold"


    An even simpler approach is to use the XOR operator on the old style with the new flag that you want to toggle. This way, you don't need to check the style first.

    private void btnBold_Click(object sender, EventArgs e)
    {
        if (rtbMakale.SelectionLength > 0)
        {
            rtbMakale.SelectionFont = new Font(rtbMakale.SelectionFont,
                rtbMakale.SelectionFont.Style ^ FontStyle.Bold);
        }
    }