Sorry,Are you targeting .NET Framework 4.8, or .NET Core 3.x, or NET 5 ?
MenuString
and ContextMenuString
instead.I am trying to use RadioCheck which is not available under the current menu system. I have a requirement to build a menu that has CheckBox or RadioButton along with a separate image. So I guess I'll do it in code then. Thanks!I don't use the WinForms Designer, so I don't know. I've not used it since VS2008. I was expecting to find them under the "Menus & Toolbars" group since that is where they used to be in old versions of Visual Studio. I suspect that they deliberately hid those controls in newer version of VS because they want you to use the forward compatibleMenuString
andContextMenuString
instead.
ToolStripMenuStrip
has Checked
property that you could use.It has Checked, but not RadioCheck.I believe that theToolStripMenuStrip
hasChecked
property that you could use.
You can add other controls like RadioButton to strip by using ToolStripControlHost.
RadioButtons
work as a group so I would assume that each ToolStripControlHost
would be considered a single group. That means that you'll still have to add your own code to uncheck other items when an item is checked./// <summary>
/// Ensures that only one <see cref="ToolStripMenuItem"/> is checked at a time on a <see cref="System.Windows.Forms.ToolStripDropDown"/>
/// </summary>
public class ToolStripDropDownRadioCheckManager
{
/// <summary>
/// The <see cref="ToolStripDropDown"/> whose items should exhibit radio-check behaviour.
/// </summary>
private ToolStripDropDown _toolStripDropDown;
/// <summary>
/// Gets or sets the <see cref="ToolStripDropDown"/> whose items should exhibit radio-check behaviour.
/// </summary>
public ToolStripDropDown ToolStripDropDown
{
get => _toolStripDropDown;
set
{
if (_toolStripDropDown != value)
{
if (_toolStripDropDown != null)
{
// Remove event handler from old drop-down.
_toolStripDropDown.ItemClicked -= ToolStripDropDown_ItemClicked;
}
_toolStripDropDown = value;
// Add event handler to new drop-down.
_toolStripDropDown.ItemClicked += ToolStripDropDown_ItemClicked;
}
}
}
public ToolStripDropDownRadioCheckManager() { }
public ToolStripDropDownRadioCheckManager(ToolStripDropDown toolStripDropDown)
{
this.ToolStripDropDown = toolStripDropDown;
}
private void ToolStripDropDown_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
if (e.ClickedItem is ToolStripMenuItem clickedItem &&
clickedItem.CheckOnClick &&
!clickedItem.Checked)
{
// The user has clicked an item that is not currently checked and will be checked automatically.
// The get currently checked item, if there is one.
var checkedMenuItem = ToolStripDropDown.Items
.OfType<ToolStripMenuItem>()
.SingleOrDefault(tsmi => tsmi.Checked);
if (checkedMenuItem != null)
{
checkedMenuItem.Checked = false;
}
}
}
}
ContextMenuStrip
and a ToolStripMenuItem
on a MenuStrip
. All you have to do is make sure that CheckOnClick
is true
for each menu item and then create an instance and associate it appropriately. Here's the code I used to test it:private ToolStripDropDownRadioCheckManager mainRadioCheckManager;
private ToolStripDropDownRadioCheckManager contextRadioCheckManager;
private void Form1_Load(object sender, EventArgs e)
{
mainRadioCheckManager = new ToolStripDropDownRadioCheckManager(parentToolStripMenuItem.DropDown);
contextRadioCheckManager = new ToolStripDropDownRadioCheckManager(contextMenuStrip1);
}
I just did a quick test, each DropDownItems collection is a separate radio group, as would be natural. That also goes for the root Items collections.RadioButtons
work as a group so I would assume that eachToolStripControlHost
would be considered a single group. That means that you'll still have to add your own code to uncheck other items when an item is checked.
Thanks for the example!I just did a quick test, each DropDownItems collection is a separate radio group, as would be natural. That also goes for the root Items collections.