We have a WinForms app for .NET Framework 4.7.2. The main form contains a toolbar based on the ToolStrip component. One of the buttons displays a drop-down menu based on the ContextMenuStrip component. The whole construction looks like this:
private ToolStrip MainToolStrip;
private ToolStripDropDownButton TextSizeButton;
private ContextMenuStrip TextSizeMenu;
MainToolStrip = new ToolStrip();
TextSizeButton = new ToolStripDropDownButton();
TextSizeMenu = new ContextMenuStrip();
MainToolStrip.Items.AddRange(new ToolStripItem[] {..., TextSizeButton, ...});
TextSizeButton.DropDown = TextSizeMenu;
High dpi support is enabled in the app using the standard <System.Windows.Forms.ApplicationConfigurationSection>
element in the app config file (according to this Microsoft guide).
This drop-down menu looks good on a normal 96dpi screen, but the picture is not so good on a high-res screen because the width of the gray area for check mark is not enough:
How to fix this issue?
To avoid any further incompatibilities and side effects related to the standard implementation of check marks in ContextMenuStrip
, we decided to simply use our own image as the check mark:
It looks even cooler than the default one because the default implementation draws the selection rectangle around the check mark (why?!):
The core part of code that switches the check state is the following:
private Bitmap ImageCheck = CreateToolButtonResBitmap("check.png");
private Bitmap ImageEmpty = CreateToolButtonResBitmap("10tec-empty.png");
private void SetMenuItemChecked(ToolStripMenuItem item, bool check)
{
if (check)
item.Image = ImageCheck;
else
item.Image = ImageEmpty;
}
And we also remove the unneeded gray area at the left of ContextMenuStrip
for better effect:
internal class DropDownToolbarRenderer : ToolStripProfessionalRenderer
{
protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)
{
}
}
private static DropDownToolbarRenderer fDropDownToolbarRenderer = new DropDownToolbarRenderer();
TextSizeMenu.Renderer = fDropDownToolbarRenderer;