简体   繁体   中英

How to remove right side empty space in ToolStripMenuItem

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;
    }

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))

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM