[Mono-dev] [Mono-winforms-list] [BUMP] ToolStripDropDown + UserControl

Alex Shulgin alexander.shulgin at yessoftware.com
Tue Mar 3 11:19:17 EST 2009


Alex Shulgin wrote:
> Alex Shulgin wrote:
>> Hi,
>>
>> I'm trying to add some custom control to ToolStripDropDown using 
>> ToolStripControlHost.
>>
>> This works fine with .NET, but with Mono (2.2) the control is always 
>> resized to 22 pixels tall...  Too bad I can't find a workaround for a 
>> few days now.
>>
>> Any help & suggestions are much appreciated. :)
> 
> If someone could tell how to create a popup window w/o using 
> ToolStripDropDown I'd be grateful.
> 
> Since it's exactly the thing I'm trying to accomplish--using 
> ToolStripDropDown is just the shortest way in .NET, but it seems to be 
> broken in Mono.

Hi All again!

I've done some more research on the issue.

While browsing through mono's System.Windows.Forms sources I've come 
across the following suspicious piece of code in ToolStripDropDown.OnLayout:

if (tsi is ToolStripSeparator)
     height = 7;
else
     height = 22;

http://preview.tinyurl.com/cdmrqu

This code is exactly what causes the described problem.  So I propose 
the following patch:

--- ToolStripDropDown.cs~	2009-02-14 01:55:14.000000000 +0200
+++ ToolStripDropDown.cs	2009-03-03 17:57:10.000000000 +0200
@@ -579,19 +579,24 @@
  		{
  			// Find the widest menu item
  			int widest = 0;
+			bool haveStandardItems = false;

  			foreach (ToolStripItem tsi in this.Items) {
  				if (!tsi.Available)
  					continue;
+
+				if (!(tsi is ToolStripControlHost))
+					haveStandardItems = true;
  					
  				tsi.SetPlacement (ToolStripItemPlacement.Main);
  				
-				if (tsi.GetPreferredSize (Size.Empty).Width > widest)
-					widest = tsi.GetPreferredSize (Size.Empty).Width;
+				widest = Math.Max (widest, tsi.GetPreferredSize (Size.Empty).Width);
  			}
-			
+
  			int x = this.Padding.Left;
-			widest += 68 - this.Padding.Horizontal;
+			if (haveStandardItems)
+				widest += 68 - this.Padding.Horizontal;
+
  			int y = this.Padding.Top;

  			foreach (ToolStripItem tsi in this.Items) {
@@ -604,11 +609,13 @@

  				if (tsi is ToolStripSeparator)
  					height = 7;
+				else if (tsi is ToolStripControlHost)
+					height = tsi.GetPreferredSize (Size.Empty).Height;
  				else
  					height = 22;

  				tsi.SetBounds (new Rectangle (x, y, widest, height));
-				y += tsi.Height + tsi.Margin.Bottom;
+				y += /*tsi.Height*/ height + tsi.Margin.Bottom;
  			}

  			this.Size = new Size (widest + this.Padding.Horizontal, y + 
this.Padding.Bottom);// + 2);


--8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<--

It uses a call to GetPreferredSize for ToolStripControlHost items 
instead of hard-coded value 22 (which is bizarre anyway).

The patch also preserves current behavior when the drop down menu is 
populated with 'standard' items like ToolStripButton, ToolStripLabel, 
etc. or a mix of standard and hosted custom items, so the things won't 
break.

If there's only custom items hosted via ToolStripControlHost the drop 
down now mimics 'correct' behavior of .NET ToolStripDropDown: the items 
are painted in full size and w/o decoration.

Btw, what's that another hard-coded value of 68?  Isn't this too much 
for a single method?.. :)

--
Thanks all,
Alex
PS: I really, really need some feedback on this issue...


More information about the Mono-devel-list mailing list