1

I have a RTF box in my C# WinForms app.

Setting basic styles is fairly simple but when I try to unset the Italic style I lose all other applied styles to the selection font.

if (rtf.SelectionFont.Style.HasFlag(FontStyle.Italic))
{
     rtf.SelectionFont = new Font(rtf.SelectionFont.FontFamily, rtf.SelectionFont.Size, rtf.SelectionFont.Style | FontStyle.Regular);
}
else
{
     rtf.SelectionFont = new Font(rtf.SelectionFont.FontFamily, rtf.SelectionFont.Size, rtf.SelectionFont.Style | FontStyle.Italic);
}

Is there a way to just de-select the italic property without losing the Bold,underline ect.

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
IEnumerable
  • 3,610
  • 14
  • 49
  • 78
  • 2
    FontStyle.Regular is 0, it doesn't change anything. You have to use the ~ operator, as shown in [this answer](http://stackoverflow.com/a/3153514/17034). – Hans Passant Feb 24 '14 at 01:55
  • The `&` and `~` operators in conjunction will work, but _have to_ is overstated - [TMTOWTDI](http://en.wikipedia.org/wiki/TMTOWTDI), ["potato, potato, tomato, tomato"](http://answers.yahoo.com/question/index?qid=20100307223452AAAez19) etc. – J0e3gan Feb 24 '14 at 02:29
  • Possible duplicate of [Substract Flag From FontStyle (Toggling FontStyles) \[C#\]](http://stackoverflow.com/questions/4198429/substract-flag-from-fontstyle-toggling-fontstyles-c) – Jim Fell May 20 '16 at 14:38

2 Answers2

2

You should try iterating over the enumeration and putting the style back together. Something like the following:

FontStyle oldStyle = rtf.SelectionFont.Style;
FontStyle newStyle = FontStyle.Regular;
foreach (Enum value in Enum.GetValues(oldStyle.GetType()))
{
    if (oldStyle.HasFlag(value) && !value.Equals(FontStyle.Italic))
    {
        newStyle = newStyle | (FontStyle)value;
    }
}

rtf.SelectionFont = new Font(rtf.SelectionFont.FontFamily, rtf.SelectionFont.Size, newStyle);
OxCantEven
  • 629
  • 4
  • 9
2

Use an XOR rather than an OR to remove a single FontStyle - for example:

private void btnBold_Click(object sender, EventArgs e)
{
    var currentStyle = rtf.SelectionFont.Style;
    var newStyle =
        rtf.SelectionFont.Bold ?
        currentStyle ^ FontStyle.Bold :
        currentStyle | FontStyle.Bold;

    rtf.SelectionFont =
        new Font(
            rtf.SelectionFont.FontFamily,
            rtf.SelectionFont.Size,
            newStyle);
}

private void btnItalic_Click(object sender, EventArgs e)
{
    var currentStyle = rtf.SelectionFont.Style;
    var newStyle =
        rtf.SelectionFont.Italic ?
        currentStyle ^ FontStyle.Italic :
        currentStyle | FontStyle.Italic;

    rtf.SelectionFont =
        new Font(
            rtf.SelectionFont.FontFamily,
            rtf.SelectionFont.Size,
            newStyle);
}

With this implementation, removing the bold or italic style will not affect the other style if it is already applied to the selection.

BONUS:

For additional considerations like reselecting the selection after changing its style, an old DevX tip of the day might interest you too.

Also, the common logic in the style-specific handlers I offered begs to be factored out into a helper method that the style-specific handlers can leverage - e.g. private ChangeStyle(FontStyle style).

J0e3gan
  • 8,740
  • 10
  • 53
  • 80