Welche Methode muss überschrieben werden, um die Ecke von NotiIcons ContextMenuStrip abzurunden?
Posted: 20 Jan 2025, 19:07
In Windows 11 habe ich festgestellt, dass das Kontextmenü fast jedes Systray-Symbols eine runde Ecke hat.
Da es kein Systray-Menü für WPF-Anwendungen gibt, habe ich das Windows-Formular NotiIcon und ContextMenuStrip verwendet.
I haben ToolStripProfessionalRenderer mit ProfessionalColorTable vollständig angepasst, um den Dunkelmodus
gemäß den Anforderungen der Kunden zu unterstützen. Jetzt suche ich nach einer Umrundung. Mir wurde „RoundedEdges = true;“
verwendet, aber es hat nicht funktioniert. Ich muss genau wissen, welche Methode überschrieben werden muss, um die Ecke von ContextMenuStrip zu umgehen.
[img]https://i.sstatic.net /vFke0.png[/img]
Hier unten ist mein Renderer-Beispielcode.
Update:
Kürzlich wurde versucht, die OnPaint()-Methode zu überschreiben. Aber die runde Ecke ist nicht glatt und auch das Untermenü ist nicht abgerundet.

Vielen Dank im Voraus. Wir freuen uns über jede Hilfe.
Da es kein Systray-Menü für WPF-Anwendungen gibt, habe ich das Windows-Formular NotiIcon und ContextMenuStrip verwendet.
I haben ToolStripProfessionalRenderer mit ProfessionalColorTable vollständig angepasst, um den Dunkelmodus
gemäß den Anforderungen der Kunden zu unterstützen. Jetzt suche ich nach einer Umrundung. Mir wurde „RoundedEdges = true;“
verwendet, aber es hat nicht funktioniert. Ich muss genau wissen, welche Methode überschrieben werden muss, um die Ecke von ContextMenuStrip zu umgehen.
[img]https://i.sstatic.net /vFke0.png[/img]
Hier unten ist mein Renderer-Beispielcode.
Code: Select all
///Menu Renderer
public class MenuRenderer : ToolStripProfessionalRenderer
{
//Fields
private Color primaryColor;
private Color textColor;
private int arrowThickness;
private WindowsTheme systrayTheme;
[Browsable(false)]
public WindowsTheme SystrayTheme
{
get { return systrayTheme; }
set { systrayTheme = value; }
}
//Constructor
public MenuRenderer(bool isMainMenu, Color primaryColor, Color textColor, Color menuItemMouseOverColor, Color menuItemMouseOverBorderColor, WindowsTheme theme)
: base(new MenuColorTable(isMainMenu, primaryColor, menuItemMouseOverColor, menuItemMouseOverBorderColor, theme))
{
RoundedEdges = true;
this.primaryColor = primaryColor;
this.systrayTheme = theme;
if (isMainMenu)
{
arrowThickness = 2;
if (textColor == Color.Empty) //Set Default Color
this.textColor = Color.Gainsboro;
else//Set custom text color
this.textColor = textColor;
}
else
{
arrowThickness = 1;
if (textColor == Color.Empty) //Set Default Color
this.textColor = Color.DimGray;
else//Set custom text color
this.textColor = textColor;
}
}
//Overrides
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
base.OnRenderItemText(e);
e.Item.ForeColor = e.Item.Selected ? Color.White : textColor;
}
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
//Fields
var graph = e.Graphics;
var arrowSize = new Size(5, 10);
var arrowColor = e.Item.Selected ? Color.White : primaryColor;
var rect = new Rectangle(e.ArrowRectangle.Location.X, (e.ArrowRectangle.Height - arrowSize.Height) / 2,
arrowSize.Width, arrowSize.Height);
using (GraphicsPath path = new GraphicsPath())
using (Pen pen = new Pen(arrowColor, arrowThickness))
{
//Drawing
graph.SmoothingMode = SmoothingMode.AntiAlias;
path.AddLine(rect.Left, rect.Top, rect.Right, rect.Top + rect.Height / 2);
path.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Left, rect.Top + rect.Height);
graph.DrawPath(pen, path);
}
}
protected override void OnRenderGrip(ToolStripGripRenderEventArgs e)
{
Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
GraphicsPath graphicsPath = RoundedRect(rectangle, 8);
using (Pen pen = new Pen(Color.Green,5))
{
e.Graphics.DrawPath(pen, graphicsPath);
//e.Graphics.FillPath(pen.Brush, graphicsPath);
}
}
protected override void OnRenderToolStripPanelBackground(ToolStripPanelRenderEventArgs e)
{
//base.OnRenderToolStripPanelBackground(e);
Rectangle rectangle = new Rectangle(e.ToolStripPanel.Location.X, e.ToolStripPanel.Location.Y,
e.ToolStripPanel.ClientRectangle.Width, e.ToolStripPanel.ClientRectangle.Height);
GraphicsPath graphicsPath = RoundedRect(rectangle, 8);
using (Pen pen = new Pen(Color.Green, 5))
{
//e.Graphics.DrawPath(pen, graphicsPath);
e.Graphics.FillPath(pen.Brush, graphicsPath);
}
}
protected override void OnRenderStatusStripSizingGrip(ToolStripRenderEventArgs e)
{
//base.OnRenderStatusStripSizingGrip(e);
Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
GraphicsPath graphicsPath = RoundedRect(rectangle, 8);
using (Pen pen = new Pen(Color.Green,5))
{
e.Graphics.DrawPath(pen, graphicsPath);
//e.Graphics.FillPath(pen.Brush, graphicsPath);
}
}
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
//Fields
//var graph = e.Graphics;
//var borderZise = new Size(e.AffectedBounds.Width + 10, e.AffectedBounds.Height + 10);
//var borderColor = Color.DeepPink;
//var rect = new Rectangle(e.AffectedBounds.X, (e.AffectedBounds.Height - borderZise.Height) / 2,
// borderZise.Width, borderZise.Height);
//using (GraphicsPath path = new GraphicsPath())
//using (Pen pen = new Pen(borderColor, arrowThickness))
//{
// //Drawing
// graph.SmoothingMode = SmoothingMode.AntiAlias;
// path.AddLine(rect.Left, rect.Top, rect.Right, rect.Top + rect.Height / 2);
// path.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Left, rect.Top + rect.Height);
// graph.DrawPath(pen, path);
//}
//DrawRoundedRectangle(e.Graphics, e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width - 5, e.AffectedBounds.Height, 15, Color.Red);
//Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
//GraphicsPath graphicsPath = RoundedRect(rectangle, 8);
//using (Pen pen = new Pen(Color.Green, 2))
//{
// //e.Graphics.DrawPath(pen, graphicsPath);
// e.Graphics.FillPath(pen.Brush, graphicsPath);
//}
}
public GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
int diameter = radius * 2;
Size size = new Size(diameter, diameter);
Rectangle arc = new Rectangle(bounds.Location, size);
GraphicsPath path = new GraphicsPath();
if (radius == 0)
{
path.AddRectangle(bounds);
return path;
}
// top left arc
path.AddArc(arc, 180, 90);
// top right arc
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
// bottom right arc
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
// bottom left arc
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
}
////////Custom Menu
public class CustomContextMenu : ContextMenuStrip
{
//Fields
private bool isMainMenu;
private int menuItemHeight = 20;
private int menuItemWidth = 20;
private Color menuItemTextColor = Color.Empty;
private Color primaryColor = Color.Empty;
private Color MouseOverColor = Color.Empty;
private Color MouseOverBorderColor = Color.Empty;
private WindowsTheme systrayTheme = WindowsTheme.Light;
private Bitmap menuItemHeaderSize;
//Constructor
public CustomContextMenu()
{
}
//Properties
[Browsable(false)]
public bool IsMainMenu
{
get { return isMainMenu; }
set { isMainMenu = value; }
}
[Browsable(false)]
public int MenuItemHeight
{
get { return menuItemHeight; }
set { menuItemHeight = value; }
}
[Browsable(false)]
public int MenuItemWidth
{
get { return menuItemWidth; }
set { menuItemWidth = value; }
}
[Browsable(false)]
public Color MenuItemTextColor
{
get { return menuItemTextColor; }
set { menuItemTextColor = value; }
}
[Browsable(false)]
public Color PrimaryColor
{
get { return primaryColor; }
set { primaryColor = value; }
}
[Browsable(false)]
public Color MenuItemMouseOverColor
{
get { return MouseOverColor; }
set { MouseOverColor = value; }
}
[Browsable(false)]
public Color MenuItemMouseOverBorderColor
{
get { return MouseOverBorderColor; }
set { MouseOverBorderColor = value; }
}
[Browsable(false)]
public WindowsTheme SystrayTheme
{
get { return systrayTheme; }
set { systrayTheme = value; }
}
//Private methods
private void LoadMenuItemHeight()
{
if (isMainMenu)
menuItemHeaderSize = new Bitmap(menuItemWidth, menuItemHeight);
else menuItemHeaderSize = new Bitmap(menuItemWidth-5, menuItemHeight);
foreach (Forms.ToolStripMenuItem menuItemL1 in this.Items)
{
menuItemL1.ImageScaling = ToolStripItemImageScaling.None;
if (menuItemL1.Image == null) menuItemL1.Image = menuItemHeaderSize;
foreach (Forms.ToolStripMenuItem menuItemL2 in menuItemL1.DropDownItems)
{
menuItemL2.ImageScaling = ToolStripItemImageScaling.None;
if (menuItemL2.Image == null) menuItemL2.Image = menuItemHeaderSize;
foreach (Forms.ToolStripMenuItem menuItemL3 in menuItemL2.DropDownItems)
{
menuItemL3.ImageScaling = ToolStripItemImageScaling.None;
if (menuItemL3.Image == null) menuItemL3.Image = menuItemHeaderSize;
foreach (Forms.ToolStripMenuItem menuItemL4 in menuItemL3.DropDownItems)
{
menuItemL4.ImageScaling = ToolStripItemImageScaling.None;
if (menuItemL4.Image == null) menuItemL4.Image = menuItemHeaderSize;
///Level 5++
}
}
}
}
}
//Overrides
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (this.DesignMode == false)
{
switch (SystrayTheme)
{
case WindowsTheme.Light:
{
menuItemTextColor = Color.Black;
}
break;
case WindowsTheme.Dark:
{
menuItemTextColor = Color.White;
}
break;
case WindowsTheme.HighContrast:
{
menuItemTextColor = Utility.ToDrawingColor(System.Windows.SystemColors.MenuTextColor);
}
break;
}
this.Renderer = new MenuRenderer(isMainMenu, primaryColor, menuItemTextColor, MouseOverColor, MouseOverBorderColor, SystrayTheme);
LoadMenuItemHeight();
}
}
}
Kürzlich wurde versucht, die OnPaint()-Methode zu überschreiben. Aber die runde Ecke ist nicht glatt und auch das Untermenü ist nicht abgerundet.

Code: Select all
private GraphicsPath GetGraphicsPath(RectangleF rect,float radious)
{
GraphicsPath path = new GraphicsPath();
path.StartFigure();
path.AddArc(rect.X, rect.Y, radious, radious, 180, 90);
path.AddArc(rect.Width - radious, rect.Y, radious, radious, 270, 90);
path.AddArc(rect.Width - radious, rect.Height - radious, radious, radious, 0, 90);
path.AddArc(rect.X, rect.Height - radious, radious, radious, 90, 90);
path.CloseFigure();
return path;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
RectangleF rectSurface = new RectangleF(0, 0, this.Width, this.Height);
RectangleF rectBorder = new RectangleF(1, 1, this.Width - 0.8F, this.Height - 1);
if (borderRadius > 2) //Rounder
{
using (GraphicsPath pathSurface = GetGraphicsPath(rectSurface, borderRadius))
using (GraphicsPath pathBorder = GetGraphicsPath(rectBorder, borderRadius - 1F))
using (Pen penSurface = new Pen(this.BackColor, 2))
using (Pen penBorder = new Pen(borderColor, borderSize))
{
penBorder.Alignment = PenAlignment.Inset;
//Menu surface
this.Region = new Region(pathSurface);
//Draw surface border for HD result
e.Graphics.DrawPath(penSurface, pathSurface);
//Menu Border
if (borderSize >= 1)
e.Graphics.DrawPath(penBorder, pathBorder);
}
}
else //Normal contex menu
{
//Menu surface
this.Region = new Region(rectSurface);
//Menu border
if (borderSize >= 1)
{
using (Pen penBorder = new Pen(borderColor, borderSize))
{
penBorder.Alignment = PenAlignment.Inset;
e.Graphics.DrawRectangle(penBorder, 0, 0, this.Width - 1, this.Height - 1);
}
}
}
}
//Overrides
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (this.DesignMode == false)
{
//this.Parent.BackColorChanged += Parent_BackColorChanged;
switch (SystrayTheme)
{
case WindowsTheme.Light:
{
menuItemTextColor = Color.Black;
}
break;
case WindowsTheme.Dark:
{
menuItemTextColor = Color.White;
}
break;
case WindowsTheme.HighContrast:
{
menuItemTextColor = Utility.ToDrawingColor(System.Windows.SystemColors.MenuTextColor);
}
break;
}
this.RenderMode = ToolStripRenderMode.Professional;
this.Renderer = new MenuRenderer(isMainMenu, primaryColor, menuItemTextColor, MouseOverColor, MouseOverBorderColor, SystrayTheme);
LoadMenuItemHeight();
}
}
private void Parent_BackColorChanged(object sender, EventArgs e)
{
if (this.DesignMode)
this.Invalidate();
}