Introduction
These are multiple controls which I've been working on for several days. The "SharpComponents
" contain a (Context)MenuStrip
, a ToolStrip
and a StatusStrip
too, which all access an owner-created renderer. The renderer itself accesses the so-called "SharpDefinitions
". The basic idea of all this is simply a reusable component for multiple other controls. With a SharpDefinition
on the form, you can pass it to SharpToolStrip
, SharpMenuStrip
, SharpContextMenuStrip
and SharpStatusStrip
. They all will be painted in the same style then.
Using the Code
Using the components is quite easy. First, you drop a Sharp
(Context)MenuStrip
, SharpToolStrip
or SharpStatusStrip
on the form and add all the items and stuff you want. After doing that, you have to drop a "SharpDefinitions
"-Component on the form. Now edit the properties of the created SharpDefinitions
as you wish. As a final step, go back to your Sharp
(Whatever)Strip
and look for a category called "SharpComponents
" - there, you can choose your recently created SharpDefinitions
. If everything is done right, the menu should change its appearance.
If you have problems to determine which property belongs to which part of the strip, just take a look at these pictures. I hope I did not miss a property, file a report to me, if I actually did!
Points of Interest
If any beginner programmer is wondering how I did that, I simply added a property to each renderer, which I access through another property on the respective Strip.
In a Renderer-Class:
private SharpDefinitions sharpdefinitions;
public SharpDefinitions SharpDefinitions
{
get
{
return this.sharpdefinitions;
}
set
{
this.sharpdefinitions = value;
}
}
In a Strip-Class:
[Browsable(true), Category("SharpComponents")]
public SharpDefinitions SharpDefinitions
{
get
{
return ((SharpMenuRenderer)base.Renderer).SharpDefinitions;
}
set
{
((SharpMenuRenderer)base.Renderer).SharpDefinitions = value;
this.Invalidate(true);
}
}
What actually was a bit tricky was the drawing in the overridden method "OnRenderMenuItemBackground
". After making a good long time use of my brain, I figured out that you can determine between the items by checking if they're selected or a part of a dropdown-menu. Pretty quickly, I wrote a working solution for this:
if (this.sharpdefinitions != null)
{
if (e.Item.Enabled == true)
{
if (!e.Item.IsOnDropDown && e.Item.Selected)
{
var border_rect = new Rectangle(2, 0, e.Item.Width - 5, e.Item.Height - 2);
var back_rect = new Rectangle(3, 1, e.Item.Width - 6, e.Item.Height - 3);
var border_pen = new Pen(sharpdefinitions.SelectedBorderColor);
var back_brush = new SolidBrush(sharpdefinitions.SelectedBackColor);
e.Graphics.FillRectangle(back_brush, back_rect);
e.Graphics.DrawRectangle(border_pen, border_rect);
border_pen.Dispose();
back_brush.Dispose();
}
else if (e.Item.IsOnDropDown && e.Item.Selected)
{
var border_rect = new Rectangle(2, 0, e.Item.Width - 4, e.Item.Height - 1);
var back_rect = new Rectangle(1, 1, e.Item.Width - 3, e.Item.Height - 2);
var border_pen = new Pen(sharpdefinitions.SubMenuSelectedBorderColor);
var back_brush = new SolidBrush(sharpdefinitions.SubMenuSelectedBackColor);
e.Graphics.FillRectangle(back_brush, back_rect);
e.Graphics.DrawRectangle(border_pen, border_rect);
border_pen.Dispose();
back_brush.Dispose();
}
if (!e.Item.IsOnDropDown && ((ToolStripMenuItem)e.Item).DropDown.Visible)
{
var border_rect = new Rectangle(2, 0, e.Item.Width - 5, e.Item.Height - 2);
var back_rect = new Rectangle(3, 1, e.Item.Width - 6, e.Item.Height - 3);
var start_point = new Point(3, 1);
var end_point1 = new Point(e.Item.Width - 2, 1);
var end_point2 = new Point(3, e.Item.Height - 3);
var border_pen = new Pen(sharpdefinitions.ClickedBorderColor);
var shadow_pen = new Pen(sharpdefinitions.ClickedShadowColor);
var back_brush = new SolidBrush(sharpdefinitions.ClickedBackColor);
e.Graphics.FillRectangle(back_brush, back_rect);
e.Graphics.DrawRectangle(border_pen, border_rect);
e.Graphics.DrawLine(shadow_pen, start_point, end_point1);
e.Graphics.DrawLine(shadow_pen, start_point, end_point2);
border_pen.Dispose();
shadow_pen.Dispose();
back_brush.Dispose();
}
}
}
else
{
base.OnRenderMenuItemBackground(e);
}
Closure
I really enjoyed programming those controls and I hope you enjoy using them! If you want me to have anything implemented, not only color-wise but also other stuff, then let me know via private message or just post something in the comments below. I'd really appreciate that and process is also going faster like that!
History
25/11/2014
- Released the first version of
SharpComponents
-
Renderers for ToolStrip
, MenuStrip
and StatusStrip
fully working color-wise