6

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;
    }
Jaex
  • 4,204
  • 2
  • 34
  • 56
  • Yes it is Windows Form. – Jaex May 18 '14 at 17:14
  • 2
    You can't remove it. Seems you messed with the ShowImageMargin property. Expecting us to debug your code from a screenshot is unreasonable. Show code. – Hans Passant May 18 '14 at 17:27
  • 1
    I added codes. Even if ShowImageMargin is true still that space exist. – Jaex May 18 '14 at 17:31
  • 1
    So what if he disabled the `ShowImageMargin` property? He's not asking how to get the left margin back. He wants to remove the right margin. – Grant Winney May 18 '14 at 17:32
  • I tried disabling/enabling it still empty space exist: http://i.imgur.com/Gdn6mLn.png and no x.HotkeyInfo.ToString() method not returns string which have empty space in right side. I didn't added code before because it was just simple new ToolStripMenuItem() and other things in code was not causing this space. – Jaex May 18 '14 at 17:34
  • As Hans Passant said, you cannot remove that space. It is reserved for the 'Open Submenu' icon visible in your screen shot. To more center the text, turn ShowImageMargin back on. – John Arlen May 19 '14 at 15:33

3 Answers3

1

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))
Ark
  • 11
  • 1
  • I noticed issue now, because it is static field, it removes padding from all dropdown controls. Therefore I can't use this solution. – Jaex May 26 '17 at 21:01
  • Since each dropdown shown one at time you can set negative margin at DropDownOpening event and restore to default (0,0,8,0) at DropdownClosed event – Ark Jun 03 '17 at 03:29
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.

arbiter
  • 9,447
  • 1
  • 32
  • 43
  • Tried your code but dropdown size is wrong: https://dl.dropboxusercontent.com/u/14076298/ShareX/2014/06/cQfhLL3rPz.png – Jaex Jun 06 '14 at 14:09
  • You should understand that this is example wrested from working code, and in contrast to default behavior you must calculate drop-down width by yourself. – arbiter Jun 09 '14 at 09:18
0

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.

Jaex
  • 4,204
  • 2
  • 34
  • 56