How to remove right side empty space in ToolStripMenuItem

1.7k Views Asked by At

ss

In screenshot i marked that empty space with green rectangle, i want left and right space to be equal size in ToolStripMenuItem but right side have bigger empty area which i can't remove.

Codes:

    private void UpdateWorkflowsMenu()
    {
        ((ToolStripDropDownMenu)tsddbWorkflows.DropDown).ShowImageMargin = false;

        tsddbWorkflows.DropDownItems.Clear();

        Program.HotkeyManager.Hotkeys.ForEach<HotkeySettings>(x =>
        {
            if (x.TaskSettings.Job != HotkeyType.None && (!Program.Settings.WorkflowsOnlyShowEdited || !x.TaskSettings.IsUsingDefaultSettings))
            {
                ToolStripMenuItem tsmi = new ToolStripMenuItem(x.TaskSettings.Description);
                if (x.HotkeyInfo.IsValidHotkey) tsmi.ShortcutKeyDisplayString = " " + x.HotkeyInfo.ToString();
                tsmi.Click += (sender, e) => HandleTask(x.TaskSettings);
                tsddbWorkflows.DropDownItems.Add(tsmi);
            }
        });

        tsddbWorkflows.Visible = tsddbWorkflows.DropDownItems.Count > 0;
    }
3

There are 3 best solutions below

2
arbiter On

As answered above this space is reserved for 'open submenu' arrow, and in general I do not recommend to touch this, but of course it is possible to remove that space. And actually there is several methods to do that, but all of them require some coding. Here the snippet for simplest way to do that, you must know expected width however (it can be calculated via ToolstripItem.GetPreferredSize):

private void RecentButton_DropDownOpening(object sender, EventArgs e)
{
  ToolStripDropDownItem RecentButton = (ToolStripDropDownItem)sender;
  RecentButton.DropDown.SuspendLayout();
  try
  {
    RecentButton.DropDownItems.Clear();

    // Populate items

    RecentButton.DropDown.MinimumSize = new Size(RecentButton.Bounds.Right - DisplayRectangle.Left, 0);
    RecentButton.DropDown.MaximumSize = RecentButton.DropDown.MinimumSize;
  }
  finally
  {
    RecentButton.DropDown.ResumeLayout();
  }
}

ToolStip engine in general very flexible and it is possible to implement very interesting things using it when you know its internals.

2
Ark On

VB version (actually there are 18 pixels for arrow: 10 for size and 8 for margin, leave 2 pixels for margin)

Parent.DropDown.GetType.GetField("ArrowPadding", 
Reflection.BindingFlags.NonPublic Or 
Reflection.BindingFlags.Static).SetValue(Nothing, New Padding(0, 0, -16, 0))
0
Jaex On

Converted Ark's answer to C#:

public static void HideArrowMargin(this ToolStripDropDownItem tsddi)
{
    tsddi.DropDown.GetType().GetField("ArrowPadding", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, new Padding(0, 0, -14, 0));
}

public static void HideImageMargin(this ToolStripDropDownItem tsddi)
{
    ((ToolStripDropDownMenu)tsddi.DropDown).ShowImageMargin = false;
}

Using extension for it, that way I can use it like this in multiple places:

tsddbWorkflows.HideImageMargin();
tsddbWorkflows.HideArrowMargin();

Edit:

I noticed now because it is static field, it removes arrow padding from all controls. So this is not decent solution too.