ToolStrip.Background only changes button's background (C#/.NET/WinForms) - c#

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:
But when the bar should become red, only the buttons which the mouse hovers over become red:
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.

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();

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.

Related

Draw progress bar into button background [duplicate]

I've made a class GradientButton which suppose to be a Button which is filled with gradient background.
I draw gradient filling in the OnPaintBackground() method. Unfortunately it is never invoked, of course I added a GradientButton to a Form via toolbox:
public class GradientButton : Button {
public Color Color1 { get; set; }
public Color Color2 { get; set; }
public float Angle { get; set; }
public GradientButton() {
Color1 = Color.YellowGreen;
Color2 = Color.LightGreen;
Angle = 30;
}
protected override void OnPaintBackground(PaintEventArgs e) {
base.OnPaintBackground(e);
Debug.WriteLine("This never prints");
using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,
Color1,
Color2,
Angle)) {
e.Graphics.FillRectangle(brush, this.ClientRectangle);
}
}
protected override void OnResize(EventArgs e) {
base.OnResize(e);
Invalidate();
}
}
Question: How fill the button's background with the gradient? Why OnPaintBackground is not invoked? As far as I know it should be calledbefore OnPaint method.
This is because the Button class has ControlStyles.Opaque flag set, which according to the documentation:
If true, the control is drawn opaque and the background is not painted.
You can turn it off in your class constructor
SetStyle(ControlStyles.Opaque, false);
and your OnPaintBackground override will be invoked.
However, it would not help a lot - there is a reason the flag to be set to true - the OnPaint draws both background and face of the button, so whatever you do in OnPaintBackground will not have any affect of the button appearance. Unfortunately there is no option to paint just the background, so you need to override the OnPaint and actually draw everything yourself.
You need to set the style of the form in the constructor ...
this.SetStyle(ControlStyles.UserPaint, true);
to ensure the OnPaint method is overridden. There are many settings for the ControlStyle which you can combine
I would do this instead.
Firstly, change your constructor to this:
public GradientButton()
{
Color1 = Color.YellowGreen;
Color2 = Color.LightGreen;
Angle = 30;
Paint += new PaintEventHandler(GradientButton_Paint);
}
And then add the below procedure:
private void GradientButton_Paint(object sender,PaintEventArgs e)
{
Debug.WriteLine("This never prints");
using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,Color1,Color2,Angle))
{
e.Graphics.FillRectangle(brush, this.ClientRectangle);
}
}
I'm not entirely sure why your code doesn't work, but the way I've described always works for me. Hope that's good enough.

Alternate background color of rows in a CheckedListBox?

I need to alternate the color of the items in my CheckedListBox but "alternatingColors" is not a property of CheckedListBox.
How do I go about making the item's colors alternate?
The OnDrawItem event is inaccessible by default, but if you derive a new control based on CheckedListBox, then you can override the base event.
public class MyCheckedListBox : CheckedListBox
{
private SolidBrush primaryColor = new SolidBrush(Color.White);
private SolidBrush alternateColor = new SolidBrush(Color.LightGreen);
[Browsable(true)]
public Color PrimaryColor
{
get { return primaryColor.Color; }
set { primaryColor.Color = value; }
}
[Browsable(true)]
public Color AlternateColor
{
get { return alternateColor.Color; }
set { alternateColor.Color = value; }
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
if (Items.Count <= 0)
return;
var contentRect = e.Bounds;
contentRect.X = 16;
e.Graphics.FillRectangle(e.Index%2 == 0 ? primaryColor : alternateColor, contentRect);
e.Graphics.DrawString(Convert.ToString(Items[e.Index]), e.Font, Brushes.Black, contentRect);
}
}
It'll alternate between white and green by default. Make adjustments in the Properties panel at design time, or during runtime.
I don't think this is even possible. You may want to consider using a different control for what you need. A DataGridView might be able to work for you better.

toolStrip to have menuStrip gradient background

I have a form with a menu and a toolstrip at the top. The menuStrip has a nice looking gradient background, how can I get the same effect on the toolStrip control? I know about the RenderMode property but changing this doesn't have the desired result.
You can achieve this with a custom renderer.
public class CustomToolStripRenderer : ToolStripProfessionalRenderer
{
public CustomToolStripRenderer() { }
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
{
//you may want to change this based on the toolstrip's dock or layout style
LinearGradientMode mode = LinearGradientMode.Horizontal;
using (LinearGradientBrush b = new LinearGradientBrush(e.AffectedBounds, ColorTable.MenuStripGradientBegin, ColorTable.MenuStripGradientEnd, mode))
{
e.Graphics.FillRectangle(b, e.AffectedBounds);
}
}
}
Then set your toolstrip to use an instance of this renderer.
public Form1()
{
InitializeComponent();
CustomToolStripRenderer r = new CustomToolStripRenderer();
r.RoundedEdges = false;
toolStrip1.Renderer = r;
}

How to change the appearance of a MenuStrip [duplicate]

This question already has answers here:
How to change menu hover color
(4 answers)
Closed 9 years ago.
I add a MenuStrip in my app and is add on ManagerRenderMode at Render Mode. The problem is with the appearance, look offal. Look at those two photos, I want to change that white border of submenus in transparent, that blue rectangule that look offal on gray for the menu and for the submenu in dark gray (and his border that is a dark blue) and the border white of menu when is selected. How I can do this ?
BackColor is: 36; 36; 36 and ForeColor is LightGray.
I managed to change the blue rectangle, the white rectangle when the option is selected, the blue rectangle when I select an option of submenus, but I don't know how to change the white border, please help..
Here is the code so far...
Color culoare = Color.FromArgb(20, 20, 20);
Color culoare1 = Color.FromArgb(36, 36, 36);
public override Color MenuItemSelected
{
get { return culoare; }
}
public override Color MenuItemBorder
{
get { return culoare; }
}
public override Color MenuItemSelectedGradientBegin
{
get { return culoare; }
}
public override Color MenuItemSelectedGradientEnd
{
get { return culoare; }
}
public override Color MenuItemPressedGradientBegin
{
get { return culoare; }
}
public override Color MenuItemPressedGradientEnd
{
get { return culoare; }
}
public override Color MenuBorder
{
get { return culoare; }
}
You can do this by creating your own ColorTable, and overriding the properties you wish to change the colour of:
public class TestColorTable : ProfessionalColorTable
{
public override Color MenuItemSelected
{
get { return Color.Red; }
}
public override Color MenuBorder //added for changing the menu border
{
get { return Color.Green; }
}
}
You would use it like this:
private void Form1_Load(object sender, EventArgs e)
{
menuStrip1.Renderer = new ToolStripProfessionalRenderer(new TestColorTable());
}
Your approach is incorrect. You do not style menus and toolstrips using forecolor/backcolor.
Take a look at ToolStripProfessionalRenderer
Example on how to use this
public class MyToolStripRenderer : ToolStripProfessionalRenderer
{
/* override styling/drawing here */
}
MenuStrip strip = new MenuStrip();
strip.Renderer = new MyToolStripRenderer();
//this will set RenderMode to "Custom"
consider using this example on CodeProject as some research.
Better still, VBForums have loads of them, already implemented (in the usual Luna, Office, Windows, Visual Studio styles!)
http://www.vbforums.com/showthread.php?596563-100-Customizable-MenuStrip-ToolStrip-StatusStrip-including-common-presets
If you simply want to chaneg the colors...use Pondidum's answer! It involves less work!

How to change UIButton HighLight Color using Monotouch?

How to change UIButton HighLight Color using Monotouch?
There is no direct way to do this. You must subclass UIButton and draw it your self when is is highlighted. This is a simple example:
public class CustomButton : UIButton
{
public CustomButton(RectangleF frame)
{
this.Frame = frame;
this.AddObserver(this, new NSString("Highlighted"), NSKeyValueObservingOptions.New, IntPtr.Zero);
}
public override void ObserveValue (NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
{
if (keyPath.ToString() == "Highlighted")
{
this.SetNeedsDisplay();
}
}
public override void Draw (RectangleF rect)
{
base.Draw (rect);
if (this.Highlighted)
{
// Draw for highlighted
} else
{
// Draw for normal
}
}
}
I have translated this from this question, which has an Objective-C example: Here
One possible way to do this, you will need to create a highlighted image for the button then use:
btn.SetImage(UIImage.FromBundle("Images/btnHighlighted.png"), UIControlState.Highlighted);
I have done this in my previos anwser to post so check link that i already implemented UIButton HighLigh Color

Categories