3

I want my ToolStrip Background to change when an Item is not saved.

To render the background of my toolstrip I use my own renderer:

    class ToolStripRenderer : ToolStripProfessionalRenderer
    {
        private MenuBarForm parent;

        public ToolStripRenderer(MenuBarForm Parent)
        {
            parent = Parent;
        }

        protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
        {
            if (parent.controlItems.Last().Unsaved)
                e.Graphics.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(e.ToolStrip.ClientRectangle, SystemColors.ControlLightLight, Color.Red, 90, true), e.AffectedBounds);
            else
                e.Graphics.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(e.ToolStrip.ClientRectangle, SystemColors.ControlLightLight, SystemColors.ControlDark, 90, true), e.AffectedBounds);
        }
    }

The first time the toolstrip renders it renders correctly with a grey to dark grey design:

CorrectToolstrip

But when the bar should become red, only the buttons which the mouse hovers over become red:

IncorrectToolstrip

I would like the whole toolstrip the be red-colored at once.

I already tried changing e.AffectedBounds to e.ToolStrip.Bounds, to no avail.

Maiko Kingma
  • 929
  • 3
  • 14
  • 29
  • 1
    Sounds like it dont think it need to update the control. Have you tried calling Invalidate() on the toolstrip? To force it to update? – MrApnea Jun 02 '16 at 09:43
  • Thank you for your answer. I have added it to the question. – Maiko Kingma Jun 02 '16 at 10:19
  • Please don't post answer as a part of the question. it's confusing for future readers. Post it as an answer. – Reza Aghaei Jun 02 '16 at 10:52
  • Instead of changing background color by drawing, you can create a new color table and override relevant properties to change background color, then use it when `UnSaved` changes. – Reza Aghaei Jun 02 '16 at 10:54
  • Sounds interesting. I am not familiar with color tables. Could you sample code in which a toolstrip backgroundcolor is changed based on a property using your color table. – Maiko Kingma Jun 02 '16 at 11:11
  • Yes, I'll post an answer for you. – Reza Aghaei Jun 02 '16 at 11:12

2 Answers2

2

You can create a custom color table inheriting ProfessionalColorTable and override relevant properties to change background color:

public class CustomColorTable : ProfessionalColorTable
{
    public override Color ToolStripGradientBegin
    {
        get { return Color.Red; }
    }
    public override Color ToolStripGradientMiddle
    {
        get { return Color.Red; }
    }
    public override Color ToolStripGradientEnd
    {
        get { return SystemColors.ControlLightLight; }
    }
}

To change your ToolStrip background, assign a new ToolStripProfessionalRenderer which uses your custom color table to ToolStripManager.Renderer:

ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomColorTable());

To set the original professional renderer:

ToolStripManager.Renderer = new ToolStripProfessionalRenderer();
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Thank you for your quick answer. This solution doesn't work for me unfortunately. I tried adding your CustomColorTable with this code to change the renderer ` if (controlItems.Last().Unsaved) ToolStripManager.Renderer = new ToolStripProfessionalRenderer(); else ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomColorTable());` – Maiko Kingma Jun 02 '16 at 11:46
  • To test the solution it's enough to set `RenderMode` property of your `ToolStrip` to `ManagerRenderMode` then change `ToolStripManager.Renderer` when you need. To arrange an independent test from your `UnSaved` property you can call `ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomColorTable());` in a button click to make sure it works. – Reza Aghaei Jun 02 '16 at 11:48
  • Let me know if you have any problem applying the answer. It's tested and works properly. – Reza Aghaei Jun 02 '16 at 11:51
  • In my previous solution I did not use a `ToolStripManager`. does the `ToolStripManager` need to be connected to the `ToolStrip` for this to work? My `ToolStrip` is also inside a `ToolStripContainer` maybe this interferes with the `ToolStripManager`? – Maiko Kingma Jun 02 '16 at 12:10
  • Your `ToolStrip` will use a manager if you set `RenderMode` property of your `ToolStrip` to `ManagerRenderMode`. It's the main mechanism for skinning `ToolStrip`. – Reza Aghaei Jun 02 '16 at 12:12
0

I Found this solution Thanks to FSDaniel comment:

By adding Invalidate() to the end of the OnRenderToolStripBackground the toolstrip did indeed become fully red but also caused the application to go into a infinite loop. I solved this by creating an event that was triggered by changing the UnSaved property. The form that has the toolstrip then subscribed a method to this event which called toolstrip.Invalidate(). This way Invalidate() is only used when necessary.

Maiko Kingma
  • 929
  • 3
  • 14
  • 29