this looks like a job for... tomorrow!

Winforms 2.0 Update

It's been quite a while since we released Mono 1.2.3, and the winforms team and contributors have been busy. I often reference the MoMA reports for what areas I need to be working on. Since the MoMA reports haven't been updated to reflect things that have now been implemented since 1.2.3, I did some quick and dirty comparisons so I could filter out what's been done.

According to my numbers, as of 1.2.3 there are 995 winforms methods that people have reported as in-use in their real world applications that we are missing. Since 1.2.3, we have implemented 335 of them, leaving us with 660 to go. I think that's pretty good progress for about 2 months. As the number gets smaller, it will probably take longer to implement things, as they are generally the harder ones left.

Two of the biggest places we are missing stuff are WebBrowser and MaskedTextBox, which are the only 2 controls we are completely missing. WebBrowser accounts for 154 of the missing methods, and MaskedTextBox accounts for 66 of them. MaskedTextBox doesn't look especially hard to implement, just tedious to match all the behavior from .Net.

WebBrowser on the other hand, is going to be very tricky to do in a compatible, cross-platform way. We have to consider several things, like which rendering engine to use: Gecko, KHTML, WebKit, etc. We have to either bundle it, or have some mechanism of making sure that the system has it installed. Also, it has to expose enough API that we can map all the WebBrowser functionality into it. We've thrown ideas around many times, but have yet to come up with a plan. Given what we have left, it's probably something we are going to have to face pretty soon. :)

SetBoundsCore

This was originally going to be an email to the mono winforms list, but it got too long, and people won't read long emails, so I'm putting it here instead. The following really applies to people working inside the mono winforms assembly, not consumers of it, but someone may find it interesting.

Recently I made a pretty fundamental change to the way SetBoundsCore (and bounds setting in general). Because it seemed to go very smoothly and only broke a few easily fixable cases, I didn't really alert people the way I should have. Everaldo found a case I missed, and there's probably more, so it's important that everyone knows what the change was and how it may affect them.

SetBoundsCore looks like this:

void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)

where BoundsSpecified contains things like X, Y, Location, Width, Height, Size, All, None.

The old understanding of how this worked, and the way mono implemented it, was that the BoundsSpecified indicated what fields you actually wanted to change, and the rest of the fields would be kept the same for you. Meaning you could call it like:

SetBoundsCore (0, 0, 0, 25, BoundsSpecified.Height)

and it would only change the height for you. It turns out to be quite different than this, as seen here.

The BoundsSpecified parameter is actually indicating which of the parameters has been explicitly set by developer code. You may note that if you have a button on a form, which you then dock, when you undock it, it snaps back to its pre-dock location and size. This magic is accomplished through the BoundsSpecified.

One place where this was a problem was DefaultLayout, which was setting things using the control's Location and Size property setters. This needed to change to a SetBoundsCore call with BoundsSpecified.None, which basically made the needed bounds changes, but the bounds code knows it was not explicitly set by a user.

I doubt I explained that very well, but here's the summary. Whenever you are moving or sizing controls inside winforms, there is very little chance that you want to do so using the Bounds, Location, Left, Top, Size, Height, or Width properties. If you do, the bounds code thinks it was explicitly set by a developer/user. What you really want to do is call SetBounds with BoundsSpecified.None. For example, to change the height of something, do this:

SetBounds(Bounds.X, Bounds.Y, Bounds.Width, 25, BoundsSpecified.Height);